runOnUiThread:无法触摸View,Exception

时间:2015-04-17 15:11:52

标签: java android multithreading user-interface

我知道现在已多次发布,但似乎没有解决我的问题。我在UI线程上创建一个Loading Dialog,然后启动另一个线程,它正在做一些网络工作,并通过接口,当网络完成时,该类获得一个回调。问题是,完成后,我无法删除加载对话框,即使使用" runOnUIThread"。这是代码:

public void onClickLoginButton (View view) {
    if (!((EditText)findViewById(R.id.textNickname)).getText().toString().isEmpty() &&
            !((EditText)findViewById(R.id.textPassword)).getText().toString().isEmpty()) {
        loggingIn = new ProgressDialog(this);
        loggingIn.setTitle("Login");
        loggingIn.setMessage("Wait while logging in...");
        loggingIn.show();

        final LoginInterface callbackInterface = this;

        new Thread(new Runnable() {

            public void run() {
                Networking net = new Networking();
                net.Login(((EditText) findViewById(R.id.textNickname)).getText().toString(), ((EditText) findViewById(R.id.textPassword)).getText().toString(), callbackInterface);
            }
        }).start();
    }
}

这是在完成之后由网络内容调用的函数:

@Override
public void LoginCallback(final boolean loginSuccess, final boolean isActivated) {
    loggingIn.hide();
    loggingIn = null;

    final Context context = this;

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (loginSuccess && isActivated) {
                loggingIn.hide();
                loggingIn = null;
                finish();
            } else if (loginSuccess == false) {
                Toast.makeText(context, "Login failed! User/Password wrong", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "Login failed! Account not activated", Toast.LENGTH_SHORT).show();
            }
        }
    });

}

这是堆栈跟踪:

04-17 17:06:11.313  13018-13121/com.assigame.nidhoegger.assigame E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-1422
    Process: com.assigame.nidhoegger.assigame, PID: 13018
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6122)
            at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:850)
            at android.view.View.requestLayout(View.java:16431)
            at android.view.View.setFlags(View.java:8908)
            at android.view.View.setVisibility(View.java:6036)
            at android.app.Dialog.hide(Dialog.java:299)
            at com.assigame.nidhoegger.assigame.Login.LoginCallback(Login.java:72)
            at com.assigame.nidhoegger.assigame.Networking.Login(Networking.java:134)
            at com.assigame.nidhoegger.assigame.Login$1.run(Login.java:64)
            at java.lang.Thread.run(Thread.java:841)
04-17 17:06:11.719  13018-13018/com.assigame.nidhoegger.assigame E/WindowManager﹕ android.view.WindowLeaked: Activity com.assigame.nidhoegger.assigame.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{42284588 G.E..... R......D 0,0-684,324} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:366)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:286)
            at com.assigame.nidhoegger.assigame.Login.onClickLoginButton(Login.java:56)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at android.view.View$1.onClick(View.java:3818)
            at android.view.View.performClick(View.java:4438)
            at android.view.View$PerformClick.run(View.java:18422)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:1)

您正在调用loggingIn.hide()方法两次,并且第一次不在UI线程上。将您的代码更改为:

@覆盖

public void LoginCallback(final boolean loginSuccess, final boolean isActivated) {
    final Context context = this;
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (loginSuccess && isActivated) {
                loggingIn.hide();
                loggingIn = null;
                finish();
            } else if (loginSuccess == false) {
                Toast.makeText(context, "Login failed! User/Password wrong", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "Login failed! Account not activated", Toast.LENGTH_SHORT).show();
            }
        }
    });

}