当在setRetainInstance设置为true的片段上调用findFragmentByTag时,不会返回相同的实例



我有一个带有两个片段的单一活动应用程序:

  1. 带有所有UI的片段;
  2. 没有视图的片段,AsyncTask作为其成员,并且setRetainInstance设置为true。

目标是在activity被销毁后保持AsyncTask运行,并在应用程序恢复焦点时重用它。

我没有使用setTargetFragment,所有片段之间的通信都是通过MainActivity完成的。

我认为setRetainInstance所做的是防止片段被重新创建,并保持完全相同的实例在我的处置,所以当我调用findFragmentByTag时,重新创建一个被破坏的活动,它应该返回相同的保留实例,当它被创建,但这似乎不是情况。

结果是,我最终得到了一个在后台持续计数的noUi片段(我可以在调试器中看到私生子),另一个,重新创建了一个没有引用我正在运行的AsyncTask…

我做错了什么?

下面是一些代码:

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);
}
}

提前感谢!

我错了。使用setRetainInstance,片段仅在配置更改时保留。因此,片段状态将在屏幕旋转时保持,或者如果活动在后台但而不是,如果活动被销毁。

要达到我想要的结果,我可能应该使用Service

相关内容

  • 没有找到相关文章

最新更新