Handler 如何影响 onReceiveResult(ResultReceiver) 的调用方式?

发布于 2024-12-15 03:39:23 字数 1335 浏览 1 评论 0 原文

看,我有以下代码:

我的操作:

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*/}

所以。当我传递默认处理程序时它不会失败。我问为什么?在这两种方式中,我的代码都会被调用,但是当没有指定处理程序时,它会失败。汉德勒有什么影响力?

Look, I have the following code:

My Action:

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);

And my application fails on line "imageView.setBackgroundDrawable(bitmap)" with the following exception:

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.

But this doesn't happen when I define receiver like this (with handler):

new ResultReceiver(new Handler()){.../*here goes the same code as in the first example. nothing has been changed*/}

So. It doesn't fail when I pass a default Handler. And I ask Why? In both ways my code is invoked, but when no Handler specified it fails. What influence does Handler have?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一腔孤↑勇 2024-12-22 03:39:23

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.

淡看悲欢离合 2024-12-22 03:39:23

问题是因为 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

眼眸 2024-12-22 03:39:23

以下内容对我有用。您可以使用“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));
    ...
}

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:

class UpdateUI implements Runnable
{
    Bitmap newBitmap;

    public UpdateUI(Bitmap newBitmap) {
        this.newBitmap = newBitmap;
    }
    public void run() {
         imageView.setBackgroundDrawable(newBitmap);
    }
}

Then in your resultReceiver:

@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
    // after get your bitmap
    runOnUiThread(new UpdateUI(receivedBitmap));
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文