通过处理程序更新UI [英] Update UI through Handler

查看:283
本文介绍了通过处理程序更新UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从外部主题更新我的UI 。我不能使用runOnUiThread,因为它是用出色的库的应用程序。

I need to update my UI from an external Thread. I can't use runOnUiThread, because it's an application using StandOut libraries.

所以我创建了处理程序含有方法来更新UI的类:

So I created my Handler in the class containing methods to update the UI:

private final class UIHandler extends Handler {
    public static final int DISPLAY_UI_TOAST = 0;
    private static final int LOAD_PROFILE = 1;

    public UIHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case UIHandler.DISPLAY_UI_TOAST: {
            Context context = mw.getApplicationContext();
            Toast t = Toast.makeText(context, (String) msg.obj,
                    Toast.LENGTH_SHORT);
            t.show();
        }
        case UIHandler.LOAD_PROFILE:{
            loadProfile((String) msg.obj);
        }
        default:
            break;
        }
    }
}

和我然后我创建的消息发送到处理程序

And I then I created a method to send messages to the Handler

public void loadP(String prof){
    Message msg = uiHandler.obtainMessage(UIHandler.LOAD_PROFILE);
    msg.obj = prof;
    uiHandler.sendMessage(msg);
}

但是,当我打电话loadP(我的配置文件),应用程序崩溃与此错误:

But when I call loadP(myProfile), the app crashes with this error:

08-25 19:55:08.428: E/AndroidRuntime(8602): FATAL EXCEPTION: UIHandler
08-25 19:55:08.428: E/AndroidRuntime(8602): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4607)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:835)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.view.View.requestLayout(View.java:15129)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.view.View.requestLayout(View.java:15129)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.view.View.requestLayout(View.java:15129)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.view.ViewGroup.addView(ViewGroup.java:3249)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.view.ViewGroup.addView(ViewGroup.java:3196)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.view.ViewGroup.addView(ViewGroup.java:3172)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.elements.KeyElement.createButton(KeyElement.java:261)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.elements.KeyElement.setButton(KeyElement.java:159)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.elements.KeyElement.<init>(KeyElement.java:81)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.util.KeyElementManager.add(KeyElementManager.java:32)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.util.KeyElementManager.loadProfileUI(KeyElementManager.java:91)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.util.MapperController.loadProfileUI(MapperController.java:106)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.windows.ui.ProfilesPanel.loadProfile(ProfilesPanel.java:423)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.windows.ui.ProfilesPanel.access$1(ProfilesPanel.java:414)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at com.vektor.amapper.windows.ui.ProfilesPanel$UIHandler.handleMessage(ProfilesPanel.java:464)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.os.Looper.loop(Looper.java:137)
08-25 19:55:08.428: E/AndroidRuntime(8602):     at android.os.HandlerThread.run(HandlerThread.java:60)

我要补充的是,DISPLAY_UI_TOAST消息正在工作。

I want to add that the DISPLAY_UI_TOAST message is working.

推荐答案

您不必一直延伸处理程序类,如果你只是想处理一些消息,刚刚实施 Handler.Callback

You need not extend all Handler class if you just want to handle some messages, just implement Handler.Callback:

private final class UICallback implements Handler.Callback{
    public static final int DISPLAY_UI_TOAST = 0;
    private static final int LOAD_PROFILE = 1;

    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case UICallback.DISPLAY_UI_TOAST: {
                Context context = mw.getApplicationContext();
                Toast t = Toast.makeText(context, (String) msg.obj,
                        Toast.LENGTH_SHORT);
                t.show();
                return true;
            }
            case UICallback.LOAD_PROFILE:{
                loadProfile((String) msg.obj);
                return true;
            }
            default:
                return false;
        }
    }
}

请注意,在上面code,处理邮件时返回真,假的时候并不意味着我们的消息。

Note, in above code, true is returned when message is handled, false when message was not meant for us.

现在,创建一个处理程序的与主尺蠖(这样,所有消息在UI线程中运行),以及我们所创建的回调:

Now, create a handler with main looper (so that all messages run on UI thread ), and the callback we created:

Handler handler = new Handler(Looper.getMainLooper(),new UICallback());

这篇关于通过处理程序更新UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆