WindowManager BadTokenException:在某些设备上崩溃了我的应用

时间:2018-03-30 11:45:05

标签: android alertdialog android-alertdialog

我正在开发应用,因为它允许用户使用活动功能。当我的用户没有使用该应用程序直到15分钟...然后它会在用户被使用的最后一个活动中自动显示一个不活动的会话提醒对话框。

在这种情况下,我可以使用此BaseActivity类进行处理:

public class MyBaseActivity extends AppCompatActivity {

    public AlertDialog alertDialog;

    Context context;

    String strCheck = "";
    public Long min = 0L;
    public int min1 = 0;

    public static final long DISCONNECT_TIMEOUT = 900000; // 15 min = 15 * 60 * 1000 ms

    private  Handler disconnectHandler = new Handler(){
        public void handleMessage(Message msg) {
        }
    };

    private Runnable disconnectCallback = new Runnable() {
        @Override
        public void run() {

            AlertDialog.Builder builder = new AlertDialog.Builder(MyBaseActivity.this,R.style.DialogLevelsStyle);
            builder.setTitle("USER IN-ACTIVE");
            builder.setMessage("Due to user is inactive from last 15 minutes. Please Login Again")
                    .setCancelable(false)
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            //do things
                            Intent i = new Intent(MyBaseActivity.this, SignInActivity.class);
                            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(i);
                            finish();
                            Constant.val = 1;
                            AccountUtils.setValue("1");
                            AccountUtils.setTime("0");
                        }
                    });
            alertDialog = builder.create();
            alertDialog.show();  ///// Crash coming here  // this is line number 77

        }
    };

    public void resetDisconnectTimer(){
        Log.i("Main", "Invoking logout timer");
        //disconnectHandler.removeCallbacks(disconnectCallback);
        disconnectHandler.postDelayed(disconnectCallback, DISCONNECT_TIMEOUT);
    }

    public void stopDisconnectTimer(){
        Log.i("Main", "cancel timer");
        disconnectHandler.removeCallbacks(disconnectCallback);
    }

    @Override
    public void onUserInteraction(){
        resetDisconnectTimer();
    }

    @Override
    public void onResume() {
        super.onResume();
        stopDisconnectTimer();
        resetDisconnectTimer();
        checktimings(getCurrentTime(),AccountUtils.getTime());
        System.out.println("Main : start"+ AccountUtils.getTime());
        if(min1 >= 15){
            System.out.println("Main : Conditionnnnn"+0);
            AccountUtils.setTime("0");
            AlertDialog.Builder builder = new AlertDialog.Builder(MyBaseActivity.this,R.style.DialogLevelsStyle);
            builder.setTitle("USER IN-ACTIVE");
            builder.setMessage("Due to user is inactive from last 15 minutes. Please Login Again")
                    .setCancelable(false)
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            //do things
                            Intent i = new Intent(MyBaseActivity.this, SignInActivity.class);
                            //i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(i);
                            finish();
                            Constant.val = 1;
                            AccountUtils.setValue("1");
                            AccountUtils.setTime("0");

                        }
                    });
            alertDialog = builder.create();
            alertDialog.show();
        }else {
            System.out.println("Main : Condition"+ min1);
            AccountUtils.setTime("0");
        }
        //System.out.println("Main : Start");

    }

    @Override
    public void onStop() {
        if (isAppIsInBackground(this)) {
            AccountUtils.setTime(getCurrentTime());
            System.out.println("Main : Stop"+ getCurrentTime());
            stopDisconnectTimer();
            resetDisconnectTimer();
        }else {
            stopDisconnectTimer();
        }
        super.onStop();
        //stopDisconnectTimer();
    }

    public static boolean isAppIsInBackground(Context context) {
        boolean isInBackground = true;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
            List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    for (String activeProcess : processInfo.pkgList) {
                        if (activeProcess.equals(context.getPackageName())) {
                            isInBackground = false;
                        }
                    }
                }
            }
        } else {
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
            if (componentInfo.getPackageName().equals(context.getPackageName())) {
                isInBackground = false;
            }
        }

        return isInBackground;
    }

    public static String getCurrentTime() {
        //date output format
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        return dateFormat.format(cal.getTime());
    }

    public  void checktimings(String time, String endtime) {
        try{
            SimpleDateFormat in = new SimpleDateFormat("HH:mm:ss");
            Date tempDate = in.parse(time);
            Date tempDate1 = in.parse(endtime);

            long diff = tempDate.getTime() - tempDate1.getTime();
            min = TimeUnit.MINUTES.convert(diff, TimeUnit.MILLISECONDS);
            min1 = min.intValue();
            System.out.println("Main "+min1);

        }catch (Exception e){

        }
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        if (alertDialog != null && alertDialog.isShowing()){
            alertDialog.dismiss();
            //SignInActivity.alertDialog.dismiss();
        }
    }
}

当会话超时时,此警报对话框显示在我上次使用的活动中,当时我收到以下错误:(大部分错误发生在三星设备中)

android.view.WindowManager$BadTokenException: 
  at android.view.ViewRootImpl.setView (ViewRootImpl.java:878)
  at android.view.WindowManagerGlobal.addView (WindowManagerGlobal.java:342)
  at android.view.WindowManagerImpl.addView (WindowManagerImpl.java:97)
  at android.app.Dialog.show (Dialog.java:556)
  at com.Forewarn.ForewarnApp.MyBaseActivity$2.run (MyBaseActivity.java:77)
  at android.os.Handler.handleCallback (Handler.java:751)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:154)
  at android.app.ActivityThread.main (ActivityThread.java:6692)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1468)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1358)

我尝试使用此代码在进入另一个活动之前已经添加了所有活动窗口:

@Override
    public void onDestroy(){
        super.onDestroy();
        if (alertDialog != null && alertDialog.isShowing()){
            alertDialog.dismiss();
            //SignInActivity.alertDialog.dismiss();
        }
    }

我无法在某些Android设备中解决此错误

1 个答案:

答案 0 :(得分:0)

我的应用程序也遇到了同样的问题,很难重现,可以使用它来防止崩溃:

if (!((AppCompatActivity)YourActivity).isFinishing()) {
   try {
         AlertDialog alert = builder.create();
         alert.show();
   }
   catch (WindowManager.BadTokenException e) {
           e.printStackTrace();
   }
 }