Handler 如何影响 onReceiveResult(ResultReceiver) 的调用方式?
看,我有以下代码:
我的操作:
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(位图)”线上失败,但出现以下异常:
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*/}
所以。当我传递默认处理程序时它不会失败。我问为什么?在这两种方式中,我的代码都会被调用,但是当没有指定处理程序时,它会失败。汉德勒有什么影响力?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Handler 与 Android 框架联系在一起,并确保在 Handler 回调中运行的任何代码都在父 Activity 的主 Looper 线程上执行,该线程是所有 Activity 生命周期回调和 UI 调用的执行位置。如果你真的想了解它是如何工作的,你可以浏览 Github 上的源代码,但在处理程序中运行代码几乎可以保证将东西放在正确的位置。
The Handler ties into the Android framework and ensures that any code that is run in the Handler's callbacks is executed on the parent Activity's main Looper thread which is where all the Activity lifecycle callbacks and UI calls are made. If you really want to understand how it works you can wander through the source on Github, but running code in a Handler is pretty much guaranteed to put things in the right place.
问题是因为 imageView.setBackgroundDrawable() 是从服务的线程调用的。这是不正确的。您需要确保任何 UI 更新都是从 UI 线程执行的。
从您提供的片段中很难准确解释需要更改哪些内容。
Android 提供了许多技术来允许非 UI 线程与 UI 组件交互(Handler 类是其中的一个选项)。恕我直言,如果你想开发优秀的 Android 应用程序,这是最重要的概念之一。
一些有用的链接:
http://developer.android.com/resources/articles/ painless-threading.html
什么是 Android UiThread (UI 线程)
http://www.vogella.de/articles/ AndroidPerformance/article.html
The problem is because imageView.setBackgroundDrawable() is called from your service's thread. This is incorrect. You need to make sure that any UI update is executed from the UI thread.
It is hard to explain exactly what needs to change from the snippets you provide.
Android provides a number of techniques to allow non-UI threads to interact with UI components (and the Handler class one of the option). IMHO, this is one of the most critical concept to get right if you want to develop good Android applications.
Some useful links:
http://developer.android.com/resources/articles/painless-threading.html
What is the Android UiThread (UI thread)
http://www.vogella.de/articles/AndroidPerformance/article.html
以下内容对我有用。您可以使用“runOnUiThread”方法在 UI 活动的同一线程中运行位图更新。您应该将以下类定义为 UI 活动的内部类:
然后在您的 resultReceiver 中:
The following works for me. You can run the bitmap update in the same thread of your UI activity using "runOnUiThread" method. You should define the following class as inner class of your UI activity:
Then in your resultReceiver: