屏幕旋转后,无法通过编程方式从AsyncTask中关闭BottomSheetDialogFragment

时间:2018-07-07 10:34:48

标签: android android-asynctask

我已经寻找任何可能的类似问题,并且都与该问题无关,并且不提供此问题的解决方案。

我有一个基本的聊天实施设计,其中用户从BottomSheetDialogFragment中打开ChatFragment

BottomSheetDialogFragment负责要求用户确认他要上传所选文件,并在确认后显示上传进度。

上传完成后,BottomSheetDialogFragment会自动关闭。

如果用户在上传过程中没有旋转屏幕,一切都将正常工作。

在进行上传时旋转屏幕会发生问题。

正在上传时,旋转屏幕并在此之后完成上传,AsyncTask会调用BottomSheetDialogFragment设置的Complete侦听器。

当调用BottomSheetDialogFragment完整侦听器时,它仅执行dismiss()方法,但此时会抛出NPE,因为BottomSheetDialogFragment不再附加到任何活动。 / p>

我正在寻找一种解决方案,该解决方案不涉及使用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);
    }

}

1 个答案:

答案 0 :(得分:0)

我最后通过将AsyncTask和附加到其侦听器的类之间的通信层移到LocalBroadcast接收器来对其进行抽象。这样,AsyncTask不再向侦听器“泄漏”活动分离状态。

此外,我注意到上载可能是一项长期运行的任务,因此我完全放弃了AsyncTask并移至IntentService。