产生问题的步骤。
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)
条件解决了我的问题,但我认为这是一个绑带,而不是一个真正的解决方案。有人能否对这个问题有所了解?
答案 0 :(得分:2)
我相信正在发生的事情(有人纠正我,如果我错了)是因为你用System.exit(0)
人为地关闭了应用程序,这在Android中不是推荐的做法(据我所知) ,你的片段没有干净利落地分开。这会导致在您重新打开应用程序时恢复Fragment。
你正在做的检查if (listView != null)
是有效的,因为你的片段有点鬼。它仍然存在,但它没有附加到活动,因此无法获得对您尝试使用的ListView的引用。类似但更“有效”的检查可能是if (this.getActivity() != null)
。
答案 1 :(得分:0)
来自android系统文档
使VM停止运行,程序以给定的退出状态退出。 如果先前使用true参数,调用了runFinalizersOnExit(boolean),那么所有对象都将被正确地垃圾收集并首先完成。
不确定它会有所作为。一般来说,我从不退出()一个Android程序。