看,我有以下代码:
我的行动:
final Intent intent = new Intent(getApplicationContext(), MyService.class)
.putExtra(UploadService.EXTRA_RESULT_RECEIVER, new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
String result = resultData.getString(MyService.EXTRA_RESULT_SUCCESS);
...
imageView.setBackgroundDrawable(bitmap);// here my code fails
}
})
为MyService:
Bundle b = new Bundle();
b.putString(EXTRA_RESULT_SUCCESS, response.toString());
resultReceiver.send(0, b);
我的应用程序在“imageView.setBackgroundDrawable(bitmap)”行上失败,但有以下异常:
11-13 16:25:38.986: ERROR/AndroidRuntime(3586): FATAL EXCEPTION: IntentService[MyService]
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
但是当我定义这样的接收器(带处理程序)时,这不会发生:
new ResultReceiver(new Handler()){.../*here goes the same code as in the first example. nothing has been changed*/}
因此。当我传递默认处理程序时它不会失败。我问为什么?在这两种方式中都调用了我的代码,但是当没有Handler指定它时它会失败。 Handler有什么影响?
答案 0 :(得分:8)
Handler绑定到Android框架并确保在Handler的回调中运行的任何代码都在父Activity的主Looper线程上执行,该线程是进行所有Activity生命周期回调和UI调用的地方。如果你真的想了解它是如何工作的,你可以浏览Github上的源代码,但是在Handler中运行代码几乎可以保证把东西放在正确的位置。
答案 1 :(得分:3)
问题是因为从服务的线程调用了imageView.setBackgroundDrawable()。这是不正确的。您需要确保从UI线程执行任何UI更新。
很难准确解释从您提供的代码段中需要更改的内容。
Android提供了许多技术,允许非UI线程与UI组件交互(以及Handler类的选项之一)。恕我直言,如果您想开发优秀的Android应用程序,这是最关键的概念之一。
一些有用的链接:
http://developer.android.com/resources/articles/painless-threading.html
What is the Android UiThread (UI thread)
http://www.vogella.de/articles/AndroidPerformance/article.html
答案 2 :(得分:0)
以下适用于我。您可以使用“runOnUiThread”方法在UI活动的同一个线程中运行位图更新。您应该将以下类定义为UI活动的内部类:
class UpdateUI implements Runnable
{
Bitmap newBitmap;
public UpdateUI(Bitmap newBitmap) {
this.newBitmap = newBitmap;
}
public void run() {
imageView.setBackgroundDrawable(newBitmap);
}
}
然后在你的resultReceiver中:
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// after get your bitmap
runOnUiThread(new UpdateUI(receivedBitmap));
...
}