zoukankan      html  css  js  c++  java
  • TabActivity 切换到后台遇到的问题


    //这是有问题的代码,多关闭打开几次就会报如下异常
    /**

    09-18 10:47:21.225 8617-8617/derlinp.com.appsearch E/InputEventSender﹕ Exception dispatching finished signal.
    09-18 10:47:21.225 8617-8617/derlinp.com.appsearch E/MessageQueue-JNI﹕ Exception in MessageQueue callback: handleReceiveCallback
    09-18 10:47:21.235 8617-8617/derlinp.com.appsearch E/MessageQueue-JNI﹕ java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1377)
    at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:504)
    at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:178)
    at android.app.Activity.onKeyUp(Activity.java:2204)
    at android.view.KeyEvent.dispatch(KeyEvent.java:2694)
    at android.app.Activity.dispatchKeyEvent(Activity.java:2447)
    at android.support.v7.internal.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:49)
    at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:258)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1977)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.widget.TabHost.dispatchKeyEvent(TabHost.java:324)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2050)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1514)
    at android.app.Activity.dispatchKeyEvent(Activity.java:2442)
    at derlinp.com.appsearch.activity.MainActivity.dispatchKeyEvent(MainActivity.java:98)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1977)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:3963)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3937)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3404)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3454)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3423)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3530)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3431)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3587)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3404)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3454)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3423)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3431)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3404)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3454)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3423)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3563)
    at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3726)
    at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2028)
    at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1722)
    at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1713)
    at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2005)
    at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:138)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:5111)
    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:797)
    at com.android.internal.os.ZygoteInit.main(Zyg
    09-18 10:47:21.245 8617-8617/derlinp.com.appsearch E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: derlinp.com.appsearch, PID: 8617
    java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1377)
    at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:504)
    at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:178)
    at android.app.Activity.onKeyUp(Activity.java:2204)
    at android.view.KeyEvent.dispatch(KeyEvent.java:2694)
    at android.app.Activity.dispatchKeyEvent(Activity.java:2447)
    at android.support.v7.internal.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:49)
    at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:258)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1977)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.widget.TabHost.dispatchKeyEvent(TabHost.java:324)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1408)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2050)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1514)
    at android.app.Activity.dispatchKeyEvent(Activity.java:2442)
    at derlinp.com.appsearch.activity.MainActivity.dispatchKeyEvent(MainActivity.java:98)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1977)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:3963)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3937)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3404)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3454)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3423)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3530)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3431)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3587)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3404)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3454)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3423)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3431)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3404)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3454)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3423)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3563)
    at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3726)
    at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2028)
    at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1722)
    at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1713)
    at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2005)
    at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:138)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:5111)
    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(Zygote


    */
    //意思就是说在某个Activity被系统销毁的时候系统框架调用onSaveInstanceState方法后还执行程序就会报IllegalStateException异常,这本就是android本身的问题,在这里我刚好试到一种方法可以避免这个异常,就在执行跳转命令后返回false,不往下传,返回事件就在这里终止。就没有再报错,还有一种解决方案就是在TabActivity下的每个Activity分别重写onBackPressed()来切换到后台。这样写不会报之前的异常,只是同样的代码要写几遍,很烦

    最开始的代码
    1
    public boolean dispatchKeyEvent(KeyEvent event) { 2 if (event.getAction() == KeyEvent.ACTION_DOWN 3 && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 4 ResolveInfo launcherResolve=queryCurrentLauncher(); 5 Intent intent=new Intent(); 6 intent.addCategory(Intent.ACTION_MAIN); 7 ComponentName componentName=new ComponentName(launcherResolve.activityInfo.packageName,launcherResolve.activityInfo.name); 8 intent.setComponent(componentName); 9 startActivitySafely(intent); 10 Toast.makeText(this, "要开始切换了", Toast.LENGTH_SHORT).show(); 11 12 } 13 return super.dispatchKeyEvent(event); 14 } 15 private void startActivitySafely(Intent intent){ 16 try{ 17 startActivity(intent); 18 Toast.makeText(this, "切换到后台成功", Toast.LENGTH_SHORT).show(); 19 }catch (Exception e){ 20 Toast.makeText(this, "切换到后台失败", Toast.LENGTH_SHORT).show(); 21 e.printStackTrace(); 22 } 23 } 24 25 private ResolveInfo queryCurrentLauncher() { 26 Intent launcherIntent = new Intent(Intent.ACTION_MAIN); 27 launcherIntent.addCategory(Intent.CATEGORY_HOME); 28 launcherIntent.addCategory(Intent.CATEGORY_DEFAULT); 29 List<ResolveInfo> launcherInfoList = getPackageManager().queryIntentActivities(launcherIntent, PackageManager.MATCH_DEFAULT_ONLY); 30 31 ResolveInfo launcherResolveInfo = null; 32 ActivityManager activityManager = (ActivityManager) getSystemService(Service.ACTIVITY_SERVICE); 33 List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(30); 34 Iterator<ActivityManager.RunningTaskInfo> itInfo = tasks.iterator(); 35 while (itInfo.hasNext()) { 36 ActivityManager.RunningTaskInfo info = itInfo.next(); 37 for (ResolveInfo resolveInfo : launcherInfoList) { 38 String name1 = info.topActivity.getClassName(); 39 String namme2 = resolveInfo.activityInfo.name; 40 if (name1.equals(namme2)) { 41 //获取当前使用的桌面 42 launcherResolveInfo = resolveInfo; 43 return launcherResolveInfo;44 } 45 } 46 } 47 return launcherResolveInfo; 48 }

    修改后的代码
        public boolean dispatchKeyEvent(KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN
                    && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                    ResolveInfo launcherResolve=queryCurrentLauncher();
                    Intent intent=new Intent();
                    intent.addCategory(Intent.ACTION_MAIN);
                    ComponentName componentName=new ComponentName(launcherResolve.activityInfo.packageName,launcherResolve.activityInfo.name);
                    intent.setComponent(componentName);
                    startActivitySafely(intent);
                Toast.makeText(this, "要开始切换了", Toast.LENGTH_SHORT).show();
                return false;
            }
            return super.dispatchKeyEvent(event);
        }
        private void startActivitySafely(Intent intent){
            try{
                startActivity(intent);
                Toast.makeText(this, "切换到后台成功", Toast.LENGTH_SHORT).show();
            }catch (Exception e){
                Toast.makeText(this, "切换到后台失败", Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        }
    
        private ResolveInfo queryCurrentLauncher() {
            Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
            launcherIntent.addCategory(Intent.CATEGORY_HOME);
            launcherIntent.addCategory(Intent.CATEGORY_DEFAULT);
            List<ResolveInfo> launcherInfoList = getPackageManager().queryIntentActivities(launcherIntent, PackageManager.MATCH_DEFAULT_ONLY);
    
            ResolveInfo launcherResolveInfo = null;
            ActivityManager activityManager = (ActivityManager) getSystemService(Service.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(30);
            Iterator<ActivityManager.RunningTaskInfo> itInfo = tasks.iterator();
            while (itInfo.hasNext()) {
                ActivityManager.RunningTaskInfo info = itInfo.next();
                for (ResolveInfo resolveInfo : launcherInfoList) {
                    String name1 = info.topActivity.getClassName();
                    String namme2 = resolveInfo.activityInfo.name;
                    if (name1.equals(namme2)) {
                        //获取当前使用的桌面
                        launcherResolveInfo = resolveInfo;
                        return launcherResolveInfo;
                    }
                }
            }
            return launcherResolveInfo;
        }

    这样就避免了再TabActivity下的每个Activity中分别写切换到后台的代码。

  • 相关阅读:
    maven学习
    存储过程的作用
    数据库优化
    Springmvc整合mybatis
    Spring Mvc简介
    Axis2开发实例
    Mybatis之typeAlias配置的3种方法
    Spring AOP教程及实例
    spring AOP底层原理实现——jdk动态代理
    Java实现动态代理的两种方式
  • 原文地址:https://www.cnblogs.com/xushihai/p/4818608.html
Copyright © 2011-2022 走看看