我有一个包含两个片段的活动应用程序:
AsyncTask
,setRetainInstance
设置为true。目标是在活动被破坏后保持AsyncTask运行,并在应用程序重新聚焦时重用它。
我没有使用setTargetFragment
,片段之间的所有通信都是通过MainActivity
完成的。
我认为setRetainInstance
所做的是阻止重新创建片段并保持完全相同的实例,所以当我在重新创建被破坏的活动时调用findFragmentByTag
时,它应该返回相同的保留实例,因为它创建时,但似乎并非如此。
结果是我最终得到了一个在后台继续计数的noUi片段(我可以在调试器中看到这个混蛋),另一个,重新创建了一个没有对我运行的AsyncTask的引用...... < / p>
我做错了什么?
以下是一些代码:
public class MainActivity extends Activity
implements FragmentCounter.Callback, FragmentMainScreen.Callback {
private static final String TAG_MAINFRAGMENT = "TAG_MAINFRAGMENT";
private static final String TAG_COUNTERFRAGMENT = "TAG_COUNTERFRAGMENT";
private FragmentMainScreen mFragmentMain;
private FragmentCounter mFragmentCounter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
mFragmentMain = FragmentMainScreen.getInstance();
mFragmentCounter = FragmentCounter.getInstance();
getFragmentManager().beginTransaction()
.add(R.id.container, mFragmentMain, TAG_MAINFRAGMENT)
.add(mFragmentCounter, TAG_COUNTERFRAGMENT)
.commit();
} else {
mFragmentMain = (FragmentMainScreen) getFragmentManager()
.findFragmentByTag(TAG_MAINFRAGMENT);
//The fragment that gets returned here is not the same instance as the one
//I returned with getInstance() above.
mFragmentCounter = (FragmentCounter) getFragmentManager()
.findFragmentByTag(TAG_COUNTERFRAGMENT);
}
}
}
noGui片段:
public class FragmentCounter extends Fragment
implements CounterAsyncTask.Callback, FragmentMainScreen.Callback {
private Callback mListener;
private CounterAsyncTask mCounterTask;
public static FragmentCounter getInstance(){
return new FragmentCounter();
}
public interface Callback {
public void onData(int aValue);
}
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
if (activity instanceof Callback)
mListener = (Callback) activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return null;
}
@Override
public void onValueChanged(int value) {
//In the debugger, I can see this callback beeing called,
//even after my activity gets destroyed.
//The mListener is null since I set it that way in the onDetach to
//prevent memory leaks.
//The new activity has a different instance of this Fragment.
if (mListener != null)
mListener.onData(value);
}
@Override
public void startCounting(int from) {
mCounterTask = new CounterAsyncTask(this);
mCounterTask.execute(from);
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
AsyncTask:
public class CounterAsyncTask extends AsyncTask<Integer, Integer, Void>{
private int counter;
private Callback mListener;
private static final int SKIP = 5000;
public CounterAsyncTask(Callback listener) {
mListener = listener;
}
@Override
protected Void doInBackground(Integer...values) {
if (values != null)
counter = values[0];
while(!this.isCancelled()){
publishProgress(counter+=SKIP);
try{
Thread.sleep(SKIP);
}
catch(InterruptedException e){
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
mListener.onValueChanged(values[0]);
}
public interface Callback{
public void onValueChanged(int value);
}
}
提前致谢!
答案 0 :(得分:0)
我的错误。使用setRetainInstance,片段在配置更改时仅保留 。因此片段状态将在屏幕旋转时保持,或者如果活动在后台,则不,如果活动被破坏。
为了达到我想要的结果,我应该使用服务。