android.view.WindowLeaked 在 onClick 代码中

android.view.WindowLeaked in onClick code

我认为错误发生在这段代码处:

goDirect.setOnClickListener(
                new View.OnClickListener(){
                    @Override
                    public void onClick(View view) {

                        AlertDialog.Builder mBuilder = new AlertDialog.Builder(scanActivity.this);
                        View mView = getLayoutInflater().inflate(R.layout.serial_popup, null);

                        mBuilder.setView(mView);
                        final AlertDialog dialog = mBuilder.create();

                        dialog.show();

                        Button authButton = (Button)mView.findViewById(R.id.authButton);


                        authButton.setOnClickListener(
                                new View.OnClickListener(){
                                    @Override
                                    public void onClick(View view) {
                                        Intent myIntent = new Intent(scanActivity.this, itemSetActivity.class);
                                        startActivity(myIntent);
                                        finish();

                                        overridePendingTransition(R.xml.madefadein, R.xml.splashfadeout);
                                    }
                                }
                        );
                    }
                }
        );

此代码 return windowLeaked 异常。但我无法解决它。

要解决 windowLeaked Exception,我必须使用 dialog.dismiss 并将对话框的值更改为 null。为了在内部 class 中使用 dismiss(),我将对话框声明为最终。但声明为 final,我无法将对话框的值更改为 null。如何解决这个错误?或者是否有任何解决方案不将对话框声明为最终?

对不起,我的英语不流利。

E/WindowManager: android.view.WindowLeaked: Activity com.example.dh.qrock.scanActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{21f703da V.E..... R....... 0,0-1025,904} that was originally added here
                     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
                     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)
                     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
                     at android.app.Dialog.show(Dialog.java:298)
                     at com.example.dh.qrock.scanActivity.onClick(scanActivity.java:217)
                     at android.view.View.performClick(View.java:4757)
                     at android.view.View$PerformClick.run(View.java:19772)
                     at android.os.Handler.handleCallback(Handler.java:739)
                     at android.os.Handler.dispatchMessage(Handler.java:95)
                     at android.os.Looper.loop(Looper.java:135)
                     at android.app.ActivityThread.main(ActivityThread.java:5228)
                     at java.lang.reflect.Method.invoke(Native Method)
                     at java.lang.reflect.Method.invoke(Method.java:372)
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
Application terminated.

这是我的日志。 scanActivity:217 是 showDialog() 代码。

使用关闭日志。

09/11 19:15:37: Launching app
Cold swapped changes.
$ adb shell am start -n "com.example.dh.qrock/com.example.dh.qrock.IntroActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 26200 on device foxconn-tg_l800s-PHXGLMD5A1102221
I/art: Late-enabling -Xcheck:jni
I/InstantRun: Instant Run Runtime started. Android package is com.example.dh.qrock, real application class is null.
W/art: Failed to find OatDexFile for DexFile /data/data/com.example.dh.qrock/files/instant-run/dex/slice-slice_5-classes.dex ( canonical path /data/data/com.example.dh.qrock/files/instant-run/dex/slice-slice_5-classes.dex) with checksum 0x0b3e0e9d in OatFile /data/data/com.example.dh.qrock/cache/slice-slice_5-classes.dex
I/FirebaseInitProvider: FirebaseApp initialization unsuccessful
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
D/OpenGLRenderer: Render dirty regions requested: true
D/Atlas: Validating map...
I/Adreno-EGL: <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LA.BF.1.1.1_RB1.05.00.02.042.020_msm8974_LA.BF.1.1.1_RB1__release_AU ()
              OpenGL ES Shader Compiler Version: E031.25.03.06
              Build Date: 03/04/15 Wed
              Local Branch: mybranch8102437
              Remote Branch: quic/LA.BF.1.1.1_rb1.14
              Local Patches: NONE
              Reconstruct Branch: AU_LINUX_ANDROID_LA.BF.1.1.1_RB1.05.00.02.042.020 + 68ecddf + 5d22558 + bf8c1a3 + 746ac28 +  NOTHING
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Enabling debug mode 0
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@208829d2 time:119368343
D/AudioManager: playSoundEffect effectType:0
I/Timeline: Timeline: Activity_launch_request id:com.example.dh.qrock time:119368871
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@35a99f90 time:119369044
D/AudioManager: playSoundEffect effectType:0
I/Timeline: Timeline: Activity_launch_request id:com.example.dh.qrock time:119377512
I/System.out: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2VtYWlsIjoidGVzdEBnbWFpbC5jb20iLCJpYXQiOjE1MDUxMjQ5NDcsImV4cCI6MTUwNTcyOTc0NywiaXNzIjoieW91bmdoLmNvbSIsInN1YiI6InVzZXJJbmZvIn0.gtxYxypnPuCjpcxQDT1yOV-2y-8GArV0eIaFnPTTmhI
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@28652c6f time:119377852
D/AudioManager: playSoundEffect effectType:0
I/Timeline: Timeline: Activity_launch_request id:com.example.dh.qrock time:119378320
W/DynamiteModule: Local module descriptor class for com.google.android.gms.vision.dynamite not found.
W/ResourcesManager: Asset path '/system/framework/com.android.media.remotedisplay.jar' does not exist or contains no resources.
W/ResourcesManager: Asset path '/system/framework/com.android.location.provider.jar' does not exist or contains no resources.
I/DynamiteModule: Considering local module com.google.android.gms.vision.dynamite:0 and remote module com.google.android.gms.vision.dynamite:801
I/DynamiteModule: Selected remote version of com.google.android.gms.vision.dynamite, version >= 801
I/art: DexFile_isDexOptNeeded failed to open oat file '/data/dalvik-cache/arm/data@data@com.google.android.gms@app_chimera@m@00000015@DynamiteModulesB_GmsCore_prodlmp_xxhdpi_release.apk@classes.dex' for file location '/data/data/com.google.android.gms/app_chimera/m/00000015/DynamiteModulesB_GmsCore_prodlmp_xxhdpi_release.apk': Failed to open oat filename for reading: No such file or directory
E/Camera: JK: version=V00.13.01.00
          ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
E/Camera: JK: state=ready
          ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
I/Choreographer: Skipped 39 frames!  The application may be doing too much work on its main thread.
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@515763c time:119379342
D/AudioManager: playSoundEffect effectType:0
D/AudioManager: playSoundEffect effectType:0
I/Timeline: Timeline: Activity_launch_request id:com.example.dh.qrock time:119381058
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@23e82471 time:119381154
D/Camera: app passed NULL surface

可以将对话框声明为最终对话框并使用它们来显示或关闭。 但是你应该始终在 try catch 中包含 dialog show 或 dismiss,因为 dialog show 的父级可能消失并且你仍然无法关闭它。 如下所示。

 try{
     showDialog();
 }catch(Exception e){

 }

你能试试这个吗,

if(!isFinishing())
   dialog.show();

Button authButton = (Button)mView.findViewById(R.id.authButton);
authButton.setOnClickListener(
  new View.OnClickListener(){
    @Override
    public void onClick(View view) {
       if(dialog != null && dialog.isShowing()) {
           dialog.dismiss();
       }

       Intent myIntent = new Intent(scanActivity.this, itemSetActivity.class);
      startActivity(myIntent);
      finish();

      overridePendingTransition(R.xml.madefadein, R.xml.splashfadeout);
   }
 }
);