2015-04-17 2 views
0

Я знаю, что это было опубликовано несколько раз, но ничего, казалось, не исправить мою проблему. Я создаю диалоговое окно «Загрузка» в потоке пользовательского интерфейса, затем запускаю другой поток, который выполняет некоторые сетевые материалы и через интерфейс, класс получает обратный вызов, когда сетевое взаимодействие выполняется. Проблема в том, что после ее завершения я не могу удалить диалоговое окно загрузки даже с помощью «runOnUIThread». Вот код:runOnUiThread: Cant touch View, Exception

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

Но почему вы называете 'loggingIn.hide();' дважды в вашем методе? – AndroidEx

+0

Вы пробовали отправить свой первый «Runnable» в «Handler» на рабочий поток? Я думаю, что проблема может быть связана с тем, что ваш «Thread» не имеет всех вещей Android MessageQueue. – emerssso

+0

Android777 определил проблему - трассировка стека происходит от первого вызова, который является методом обратного вызова, а не потоком пользовательского интерфейса Runnable, и поэтому незаконно на фоновом потоке, а не на потоке пользовательского интерфейса. Вероятно, простой надзор при добавлении механизма runOnUiThread(). –

ответ

1

Вы вызываете метод loggingIn.hide() дважды, а первый раз - не в потоке пользовательского интерфейса. Измените код следующим образом:

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

} 
+0

большое спасибо. – Nidhoegger