gpt4 book ai didi

android - IllegalStateException fragment 在旋转后未附加到 onPostExecute 中的 Activity ,但未调用 onDetach

转载 作者:行者123 更新时间:2023-11-29 00:10:00 25 4
gpt4 key购买 nike

我有一个 AppCompatActivity,它使用 NavigationDrawer 模式来管理一些 fragment 。其中一个没有 setRetainInstance(true),我展示了一个 DialogFragment,里面有一个 ProgressDialog 和一个 AsyncTask,代码如下:

SavingLoader savingLoader = SavingLoader.newInstance(savingLoaderMaxValue);
savingLoader.show(getChildFragmentManager(), SAVING_LOADER_TAG);
new MyAsyncTask().execute();

SavingLoader 类是这个:

public class SavingLoader extends DialogFragment {

private static final String MAX_VALUE_TAG = "MAX_VALUE_TAG";
private static final String PROGRESS_VALUE_TAG = "PROGRESS_VALUE_TAG";

public static SavingLoader newInstance(int max_value){
SavingLoader s = new SavingLoader();
Bundle args = new Bundle();
args.putInt(MAX_VALUE_TAG, max_value);
s.setArguments(args);
return s;
}

private ProgressDialog dialog;

public SavingLoader(){}

@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setCancelable(false);
}

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
dialog = new ProgressDialog(getActivity(), getTheme());
dialog.setTitle(getString(R.string.dialog_title_saving));
dialog.setMessage(getString(R.string.dialog_message_saving));
dialog.setIndeterminate(false);
int max = (savedInstanceState == null ?
getArguments().getInt(MAX_VALUE_TAG) : savedInstanceState.getInt(MAX_VALUE_TAG));
if (max >= 1){
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress((savedInstanceState == null ?
0 : savedInstanceState.getInt(PROGRESS_VALUE_TAG)));
dialog.setMax(max);
} else dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
return dialog;
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(MAX_VALUE_TAG, dialog.getMax());
outState.putInt(PROGRESS_VALUE_TAG, dialog.getProgress());
}

public int getProgress(){
return dialog.getProgress();
}

public int getMax(){
return dialog.getMax();
}

public void incrementProgressBy(int value){
if (dialog.getProgress() + value <= dialog.getMax())
dialog.incrementProgressBy(value);
}

}

onPostExecute() 方法中,我需要执行一些 UI 更新,所以这是我的问题:如果我启动对话框和 AsyncTask(如上)并且我不旋转我的手机,所有按预期工作。如果我在 onPostExecute() 方法之后旋转手机,情况也一样。但是,如果我在 AsyncTask 仍在运行时旋转我的手机,当它完成并到达 onPostExecute() 方法时,它会给我 IllegalStateException 说托管 AsyncTask 的 fragment 和Dialogfragment 不再附加到该 Activity 。所以我试图覆盖我的 fragment 的 onAttach()onDetach() 方法(使用简单的 System.out.println) , 查看 onPostExecute() 何时被调用。结果是,当我旋转手机时,我总是得到这样的输出:

onDetach
onAttach
... (if I rotate more my phone)
onPostExecute

那么当 AsyncTask 完成时不应该附加 fragment 吗?感谢大家的时间和关注。

最佳答案

我终于设法通过停止使用 AsyncTask 并使用 LoaderManager 解决了这个问题+ AsyncTaskLoader按照这个article .简而言之,您的 fragment 必须实现 LoaderCallbacks接口(interface)和管理 AsyncTaskLoader。骨骼 fragment 可能是这样的:

public class MyFragment extends Fragment implements LoaderManager.LoaderCallbacks {

@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
// Inflate here your view as you usually do and find your components
// For example imagine to have a button tha will fire the task
Button b = (Button) view.findViewById(R.id.my_button);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Use this to start task for the first time
getLoaderManager().initLoader(0, null, this);
// .. or this for restart the task, details in
// the provided article
// getLoaderManager().restartLoader(0, null, this);
}
});

// Get fragments load manager
LoaderManager lm = getLoaderManager();
if (lm.getLoader(0) != null) {
// Reconnect to an existing loader
lm.initLoader(0, null, this);
}

// Return your view here
return view;
}

// LoaderCallbacks methods to override
@Override
public Loader onCreateLoader(int id, Bundle args) {
// Create an instance of the loader passing the context
MyTaskLoader loader = new MyTaskLoader(getActivity());
loader.forceLoad();
return loader;
}

@Override
public void onLoadFinished(Loader loader, Object data) {
// Use this callback as you would use the AsyncTask "onPostExecute"
}

@Override
public void onLoaderReset(Loader loader) {}

// Now define the loader class
private static class MyTaskLoader extends AsyncTaskLoader {
public MyTaskLoader(Context context){
super(context);
}

@Override
public Object loadInBackground() {
// Do here your async work
}
}

}

关于android - IllegalStateException fragment 在旋转后未附加到 onPostExecute 中的 Activity ,但未调用 onDetach,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31057766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com