Android 通过处理程序更新用户界面

Android 通过处理程序更新用户界面,android,android-ui,android-handler,Android,Android Ui,Android Handler,我需要从外部线程更新我的UI。我不能使用runOnUiThread,因为它是一个使用杰出库的应用程序 因此,我在包含更新UI方法的类中创建了我的处理程序: private final class UIHandler extends Handler { public static final int DISPLAY_UI_TOAST = 0; private static final int LOAD_PROFILE = 1; public UIHandler(Loope

我需要从外部
线程
更新我的UI。我不能使用runOnUiThread,因为它是一个使用杰出库的应用程序

因此,我在包含更新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;
        }
    }
}
然后我创建了一个方法将消息发送到
处理程序

public void loadP(String prof){
    Message msg = uiHandler.obtainMessage(UIHandler.LOAD_PROFILE);
    msg.obj = prof;
    uiHandler.sendMessage(msg);
}
但当我调用loadP(myProfile)时,应用程序会崩溃,并出现以下错误:

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)
08-25 19:55:08.428:E/AndroidRuntime(8602):致命异常:UIHandler
08-25 19:55:08.428:E/AndroidRuntime(8602):android.view.ViewRootImpl$CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图。
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4607)
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:835)
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.view.view.requestLayout(view.java:15129)上
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.view.view.requestLayout(view.java:15129)上
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.view.view.requestLayout(view.java:15129)上
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.view.ViewGroup.addView(ViewGroup.java:3249)上
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.view.ViewGroup.addView(ViewGroup.java:3196)上
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.view.ViewGroup.addView(ViewGroup.java:3172)上
08-25 19:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.elements.keyement.createButton(keyement.java:261)
08-25 19:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.elements.KeyElement.setButton(KeyElement.java:159)
08-2519:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.elements.KeyElement。(KeyElement.java:81)
08-25 19:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.util.keyementManager.add(keyementManager.java:32)
08-25 19:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.util.KeyElementManager.loadProfileUI(KeyElementManager.java:91)
08-25 19:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.util.MapperController.loadProfileUI(MapperController.java:106)
08-25 19:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.windows.ui.ProfilesPanel.loadProfile(ProfilesPanel.java:423)
08-25 19:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.windows.ui.ProfilesPanel.access$1(ProfilesPanel.java:414)
08-25 19:55:08.428:E/AndroidRuntime(8602):位于com.vektor.amapper.windows.ui.ProfilesPanel$UIHandler.handleMessage(ProfilesPanel.java:464)
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.os.Handler.dispatchMessage(Handler.java:99)上
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.os.Looper.loop(Looper.java:137)上
08-25 19:55:08.428:E/AndroidRuntime(8602):在android.os.HandlerThread.run(HandlerThread.java:60)上

我想补充一点,DISPLAY\u UI\u TOAST消息正在运行。

请参考下面的链接,您可以获得一些想法


您不需要扩展所有
处理程序
类如果您只想处理一些消息,只需实现
处理程序。回调

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;
        }
    }
}
注意,在上面的代码中,当消息被处理时返回true,当消息不是针对我们时返回false

现在,使用主循环器创建一个处理程序(以便所有消息都在UI线程上运行),并创建回调:

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

只有ui线程可以更新触摸视图。