Android - 由于权限被禁用,应用程序被操作系统强行关闭后,应用程序因重新启动而崩溃

时间:2016-03-09 18:31:08

标签: android android-fragments android-fragmentactivity android-lifecycle

产生问题的步骤。

1) Launch Tasks.class activity
2) Hit home button puting the app in the background
3) Go to Settings->permissions and disable a permission which results in my app being force closed by the OS
4) Open app from launcher ---> app resumes Tasks.class activity instead of opening MainActivity --> CRASH

它在listView.setAdapter(mAdapter);崩溃,因为listView现在为null,所有类变量都是null;这是我的活动。它使用TasksFragment类作为数据保留器来处理方向更改。创建TasksFragment时,它开始使用AsyncTask加载数据,并在使用回调获取新数据时通知活动

public class Tasks extends FragmentActivity  implements TasksFragment.TaskCallbacks{

   TasksFragment f;
   FragmentManager fm;
   String TASKS_TAG="TASKS";
   searchList = new ArrayList<Task>();
   TaskAdapter mAdapter;
   ListView listView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_tasks);
      .
      .
      .
      fm = getSupportFragmentManager();
      f = (TasksFragment) fm.findFragmentByTag(TASKS_TAG);
      if (f == null) {
          f = new TasksFragment();
          fm.beginTransaction().add(f, TASKS_TAG).commit();
      }
      else{
          preLoad();
          postLoad();
      } 

   }

   @Override        //TaskFragmentCallback
   public void onPreExecute() { 
       preLoad(); 
   }

   @Override        //TaskFragmentCallback
   public void onProgressUpdate(Task task) {
       searchList.add(task);
       mAdapter.notifyDataSetChanged(); 
   }

   @Override        //TaskFragmentCallback
   public void onCancelled() { }

   @Override       //TaskFragmentCallback
   public void onPostExecute() { 
       postLoad(); 
   }

   public void preLoad(){
       searchList = new ArrayList<Task>();
       mAdapter = new TaskAdapter(this,searchList,true); 
       listView.setAdapter(mAdapter);
   }

   public void postLoad(){
       searchList.clear();
       searchList.addAll(f.taskList);
       mAdapter.notifyDataSetChanged(); 
   } 
}

我设法让它不会崩溃,用

替换onPreExecute回调
   @Override        //TaskFragmentCallback
   public void onPreExecute() { 
       if(listView!=null){ 
           preLoad();  
       }
   }

我使用日志语句来确定事件的顺序,我看到了以下内容:

第一个应用程序启动和lauch Tasks.class

ON ACTIVITY CREATE 
ON FRAGMENT CREATE 
on pre execute callback
preload called by callback   
ON ACTIVITY RESUME

在应用程序终止后重新打开,同时打开Tasks.class并将应用程序置于后台

ON FRAGMENT CREATE
on pre execute callback //this is where it would crash
ON ACTIVITY CREATE
preload called by activity because fragment!=null  
ON ACTIVITY RESUME

我无法理解为什么片段是在活动之前创建的......是谁创建了这个片段?虽然if(listView!=null)条件解决了我的问题,但我认为这是一个绑带,而不是一个真正的解决方案。有人能否对这个问题有所了解?

2 个答案:

答案 0 :(得分:2)

我相信正在发生的事情(有人纠正我,如果我错了)是因为你用System.exit(0)人为地关闭了应用程序,这在Android中不是推荐的做法(据我所知) ,你的片段没有干净利落地分开。这会导致在您重新打开应用程序时恢复Fragment。

你正在做的检查if (listView != null)是有效的,因为你的片段有点鬼。它仍然存在,但它没有附加到活动,因此无法获得对您尝试使用的ListView的引用。类似但更“有效”的检查可能是if (this.getActivity() != null)

答案 1 :(得分:0)

来自android系统文档

使VM停止运行,程序以给定的退出状态退出。 如果先前使用true参数调用了runFinalizersOnExit(boolean),那么所有对象都将被正确地垃圾收集并首先完成。

不确定它会有所作为。一般来说,我从不退出()一个Android程序。