【问题标题】:Activity has leaked windowActivity 已泄露窗口
【发布时间】:2011-08-31 02:57:00
【问题描述】:

在我的初始屏幕中,我做了它来检测是否启用了 wifi 或 3g。如果不是,则对话框屏幕会提示用户退出并打开其中一个。如果它打开,则代码将继续。我的 logcat 中不断收到关于我的活动有泄漏窗口的错误。我不知道如何解决这个问题。下面的代码和logcat。有什么想法吗?

这是我的代码:

//create alert dialog for wifi and 3g
connectionDialog = new AlertDialog.Builder(SplashMain.this).create();
Log.d(TAG, "dialog created");
connectionDialog.setTitle("Wifi or 3G not detected. Please enable either Wifi or 3G");
connectionDialog.setButton("Exit", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
            finish();
    }
});

wifiHandler = new Handler();
setContentView(R.layout.splashscreen);  //Make the splash screen load first
Thread splashScreenTimer = new Thread(){ //create a timer for the splash screen
    public void run(){      //create a run class
        Looper.prepare();   //prepare looper
        try{            //methods within the run class
            int screenTimer =0;
            //make it last 3 seconds - create a while loop
            while(screenTimer <3000){
                sleep(100); //100= 1/10th of a second
                screenTimer = screenTimer +100;
            }
            connectionState();  //check wifi stuff
            Log.d(TAG, "checked wifi state");
            if(mobile == true || wifi == true){
                Log.d(TAG, "wifi is true");
                connectionDialog.dismiss();
                startActivity (new Intent("ravebox.dev.sdr.CLEARSCREEN"));
                finish();
                Log.d(TAG, "started activity");
            }
            if(mobile == false || wifi == false){
                Log.d(TAG, "wifi is false");
                wifiHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, "show dialog");
                        connectionDialog.show();
                        Log.d(TAG, "show'd dialog");
                    }
                });
            }//add activity to the manifest
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            //finish();
        }
    }
};
splashScreenTimer.start();

原木猫:

08-30 22:45:32.188: ERROR/WindowManager(334): Activity ravebox.dev.sdr.SplashMain has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405377e0 that was originally added here
08-30 22:45:32.188: ERROR/WindowManager(334): android.view.WindowLeaked: Activity ravebox.dev.sdr.SplashMain has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405377e0 that was originally added here
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.view.ViewRoot.<init>(ViewRoot.java:258)
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.view.Window$LocalWindowManager.addView(Window.java:465)
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.app.Dialog.show(Dialog.java:241)
08-30 22:45:32.188: ERROR/WindowManager(334):     at ravebox.dev.sdr.SplashMain$2$1.run(SplashMain.java:90)
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.os.Handler.handleCallback(Handler.java:587)
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.os.Looper.loop(Looper.java:123)
08-30 22:45:32.188: ERROR/WindowManager(334):     at android.app.ActivityThread.main(ActivityThread.java:3835)
08-30 22:45:32.188: ERROR/WindowManager(334):     at java.lang.reflect.Method.invokeNative(Native Method)
08-30 22:45:32.188: ERROR/WindowManager(334):     at java.lang.reflect.Method.invoke(Method.java:507)
08-30 22:45:32.188: ERROR/WindowManager(334):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
08-30 22:45:32.188: ERROR/WindowManager(334):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
08-30 22:45:32.188: ERROR/WindowManager(334):     at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

    标签: android android-activity window


    【解决方案1】:

    这是一个说明为什么会出现此问题的答案:Activity has leaked window that was originally added

    现在,如果你已经编写了这段代码

    if(mobile == true || wifi == true){
          Log.d(TAG, "wifi is true");
          connectionDialog.dismiss();
          startActivity (new Intent("ravebox.dev.sdr.CLEARSCREEN"));
          finish();
          Log.d(TAG, "started activity");
    }
    

    在上面的代码中,在关闭 connectionDialog.dismiss(); 之前,您在哪里显示它。

    在这段代码中,您通过connectionDialog.show(); 显示对话框,但关闭它的代码在哪里。

    if(mobile == false || wifi == false){
          Log.d(TAG, "wifi is false");
          wifiHandler.post(new Runnable() {
          @Override
          public void run() {
             Log.d(TAG, "show dialog");
             connectionDialog.show();
             Log.d(TAG, "show'd dialog");
          }
    });
    

    所以,请为此找到解决方案,应该是这样的。

    仅在开始时显示对话框,如果 wifi 已连接 cancel() 它并移动到下一个活动,如果未连接 cancel() 它一段时间后并给出未找到或未连接 wifi 的消息。

    【讨论】:

      【解决方案2】:

      我的猜测是因为您正在更新线程中的 UI。特别是这段代码:

      
          if(mobile == true || wifi == true){
             Log.d(TAG, "wifi is true");
             connectionDialog.dismiss();
             startActivity (new Intent("ravebox.dev.sdr.CLEARSCREEN"));
             finish();
             Log.d(TAG, "started activity");
          }
      

      作为替代方案,您可能希望使用 CountDownTimer 进行倒计时并在 onFinish() 方法中检查上述代码

      【讨论】:

        【解决方案3】:

        解决方案一:
        在完成您的活动之前关闭您的AlertDialog

        AlertDialog.dismiss();
        

        解决方案二:
        AndroidManifest.xml 中为您的活动添加以下字段。

        android:configChanges="orientation|keyboardHidden|navigation"
        

        【讨论】:

        • 第二种方法的实际作用是什么?
        【解决方案4】:

        查找任何可能引发异常的代码
        当“url”错误时,我得到了同样的异常,如下所示:

        String url = String.format(SOAP_REGISTER_URL, serviceCenterAddress);
            HttpTransportSE androidHttpTransport = new HttpTransportSE(url);
        

        只需设置它运行的正确网址

        【讨论】:

          猜你喜欢
          • 2014-03-16
          • 2016-06-26
          • 2020-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多