我已经寻找过任何可能的类似问题,但没有一个与这个问题有关,也没有为这个问题提供解决方案。
我有一个基本的聊天实现设计,其中用户从ChatFragment
打开BottomSheetDialogFragment
。
此BottomSheetDialogFragment
负责要求用户确认他要上传所选文件,并在确认后显示上传进度。
上传完成后,BottomSheetDialogFragment
会自动自行关闭。
如果用户在上传过程中不旋转屏幕,一切正常。
在上传过程中旋转屏幕时出现问题。
上传时,屏幕旋转,上传完成 之后,AsyncTask
调用BottomSheetDialogFragment
设置的 Complete 侦听器。
调用BottomSheetDialogFragment
Complete 侦听器时,它只是执行dismiss()
方法,但此时会引发 NPE,因为BottomSheetDialogFragment
不再附加到任何活动。
我正在寻找一种不涉及使用setRetainInstance(true)
的解决方案(我丢失了对AsyncTask
的引用(,也不涉及更改清单中的configChanges
选项。
到目前为止,我已经尝试使用所有可用的片段管理器来尝试从堆栈中弹出BottomSheetDialogFragment
,但由于它不再附加到活动,因此所有片段管理器都是空的。我还试图将其从ChatFragment
中移除,因为它包含对对话框的引用,但存在相同的问题。感觉好像AsyncTask
"分离"上下文传递给所有完整侦听器,导致所有侦听器也从活动中分离出来。
这是注释中请求的代码:
ChatFragment
public class ChatFragment extends Fragment { // That's the v4.support fragment
(...)
@Override
public void onActivityResult(int requestCode, int resultCode, final Intent data) {
if (resultCode == RESULT_OK) {
final FragmentActivity activity;
if ((activity = getActivity()) != null) {
final BottomSheet BottomSheet = new BottomSheet();
final OnFileUploadCompleteListener onFileUploadCompleteListener = new OnFileUploadCompleteListener() {
@Override
public void onComplete() {
bottomSheet.dismiss(); // tried just dismiss(); as well, makes no difference if it is dismissed from this class or from the BottomSheet itself
}
};
bottomSheet
.setOnFileUploadCompleteListener(onFileUploadCompleteListener)
.show(activity.getSupportFragmentManager(), bottomSheet.getClass().toString());
}
}
}
(...)
}
BottomSheet
public class BottomSheet extends BottomSheetDialogFragment implements FileUploadTask.OnUploadCompleteListener {
// the file upload task is initiated when the user confirms the upload
(...)
@Override
public void onUploadComplete(String response) {
if (onFileUploadCompleteListener != null) {
onFileUploadCompleteListener.onComplete();
}
dismiss();
}
public BottomSheet setOnFileUploadCompleteListener(OnFileUploadCompleteListener onFileUploadCompleteListener) {
this.onFileUploadCompleteListener = onFileUploadCompleteListener;
return this;
}
public interface OnFileUploadCompleteListener {
void onComplete();
}
(...)
}
FileUploadTask
public class FileUploadTask extends AsyncTask<File, Integer, String> {
private OnUploadCompleteListener onUploadCompleteListener;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(File... fileUploadDataParams) {
(miscellaneous file upload code)
return response;
}
@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if (onUploadCompleteListener != null) {
onUploadCompleteListener.onUploadComplete(response);
}
}
public FileUploadTask setOnUploadCompleteListener(OnUploadCompleteListener listener) {
onUploadCompleteListener = listener;
return this;
}
public interface OnUploadCompleteListener {
void onUploadComplete(String response);
}
}
我最终通过将 AsyncTask 和附加到其侦听器的类移动到 LocalBroadcast 接收器来抽象它们之间的通信层。这样,AsyncTask 就不再向侦听器"泄漏"活动分离状态。
此外,我注意到上传可能是一个长时间运行的任务,因此我完全放弃了 AsyncTask 并转移到 IntentService。