我有一个后台线程休眠 1/10 秒,然后重新循环。我希望它使屏幕无效,所以它会重绘并做一个简单的动画。似乎我可以使屏幕无效的唯一方法是如果我在 Runnable 中执行它,这假设有很多开销。
有没有办法在不使用可运行的情况下使线程内的屏幕无效?
我有一个后台线程休眠 1/10 秒,然后重新循环。我希望它使屏幕无效,所以它会重绘并做一个简单的动画。似乎我可以使屏幕无效的唯一方法是如果我在 Runnable 中执行它,这假设有很多开销。
有没有办法在不使用可运行的情况下使线程内的屏幕无效?
Android SDK 有一个用于此目的的内置 API - View.postInvalidate():
公共无效postInvalidate()
导致在事件循环的后续循环中发生无效。使用它来使来自非 UI 线程的视图无效。
仅当此视图附加到窗口时,才能从 UI 线程外部调用此方法。
也可以看看
invalidate() postInvalidateDelayed(long)
从后台线程调用任何与 UI 相关的 API 都是不合法的。因此,您将需要使用Runnable
.
如果后台线程唯一做的事情就是休眠,那么您可能无需使用线程就可以通过使用CountDownTimer
类来实现相同的效果。或者,您可以使用Handler.postAtTime()
API 安排 aRunnable
在未来某个毫秒数在您的 UI 线程上运行(同样,无需使用单独的线程)。
我实际上认为开销可以忽略不计。但是你可以使用AsyncTask
如下:
new AsyncTask<Void, Void, Void>() {
/* (non-Javadoc)
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected Void doInBackground(Void... params) {
while(true) { //probably want some other challenge here
Thread.sleep(1000 / 10);
publishProgress();
}
return null;
}
/* (non-Javadoc)
* @see android.os.AsyncTask#onProgressUpdate(Progress[])
*/
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
mMyView.invalidate();
}
}.execute();
这很好,因为 onProgressUpdate 会自动在 UIThread 上运行,因此您不必每次都创建新的可运行对象...
尝试向线程中的处理程序发送消息并在 handleMessage 中无效。它可能会起作用。或者像 Salil Pandit 所说的那样使用 AsyncTask。我认为 Async 更好。