Nidhoegger
Nidhoegger

Reputation: 5232

runOnUiThread: Cant touch the View, Exception

I know this has been posted multiple times now, but nothing seemed to fix my problem. I create a Loading Dialog on the UI thread, then start another thread which is doing some networking stuff and via interface, the class gets a callback, when networking is done. The problem is, after its done, i cant remove the loading dialog, even with "runOnUIThread". Here is the code:

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

And this is the function that gets called by the networking stuff, after its done:

@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();
            }
        }
    });

}

And this is the stack trace:

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)

Upvotes: 0

Views: 422

Answers (1)

bonnyz
bonnyz

Reputation: 13548

You are calling the loggingIn.hide() method twice, and the first time not on the UI thread. Change your code to this:

@Override

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

}

Upvotes: 1

Related Questions