Der*_*son 0 multithreading android android-custom-view
public class ThreadView extends View {
Paint paint = new Paint();
int count;
Handler uiThread = new Handler();
public ThreadView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setColor(Color.BLACK);
paint.setTextSize(80);
uiThread.post(new Runnable() {
@Override
public void run() {
while(true) {
count++;
invalidate();
}
}
});
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawText(count + "", 100, 100, paint);
}
}
Run Code Online (Sandbox Code Playgroud)
我在自定义视图中看到了针对线程的此解决方案,但是没有用。即使我的循环继续调用invalidate(),也不会继续调用,onDraw() 我还看到了一个解决方案,他们在其中实现了Runnable并覆盖了run(),这是一种更好的方法吗?
所有视图均已为其设置了处理程序,因此创建另一个视图效率很低。相反,您应该使用View类的post(Runnable action)或postDelayed(Runnable action,long delayMillis)方法。
至于您要完成的工作,我假设您提供的代码仅作为示例。如果您真的只是想更新某些文本,我会说使用TextView并在其上调用setText。当TextView知道其文本已更改时,它负责使自身失效。
但是回到您的问题。在很大程度上取决于您要更新计数变量的呈现方式的速率。当前,您将在UI线程上无休止地运行。这肯定会引起问题,因为您将使用无效调用向处理程序/事件队列发送垃圾邮件,同时阻止其他任何事情在UI线程上运行。
相反,我建议引入可配置的定时延迟,以及一种停止更新视图的方法。
例如,您可以设置为使视图每隔十分之一秒失效,并且仅在视图附加到窗口时才更新计数器(请注意,Runnable本身负责根据是否根据以下条件再次运行该视图) updateView标志的值):
public class ThreadView extends View {
private class UpdateViewRunnable implements Runnable {
public void run() {
count++;
invalidate();
if (updateView) {
postDelayed(this, DELAY_TIME_MILLIS);
}
}
}
private static final long DELAY_TIME_MILLIS = 100L;
private boolean updateView = false;
private UpdateViewRunnable updateViewRunnable = new UpdateViewRunnable();
private Paint paint = new Paint();
private int count;
public ThreadView(Context context) {
super(context);
init(context, null);
}
public ThreadView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
paint.setColor(Color.BLACK);
paint.setTextSize(80);
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawText(count + "", 100, 100, paint);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
updateView = true;
postDelayed(updateViewRunnable, DELAY_TIME_MILLIS);
}
@Override
public void onDetachedFromWindow() {
updateView = false;
super.onDetachedFromWindow();
}
}
Run Code Online (Sandbox Code Playgroud)