从onActivityResult调用的onPostExecute更新片段的UI

时间:2018-03-08 11:16:12

标签: android android-fragments android-asynctask

在我的应用程序中,我在按钮上单击以启动ACTION_OPEN_DOCUMENT的意图以选择文档。

private static final int READ_REQUEST_CODE = 42;
public void performFileSearch() {

    // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
    // browser.
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("*/*");
    String[] mimeTypes = {
            "image/*",
            "text/plain",
            "application/pdf"
    };
    intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
    startActivityForResult(intent, READ_REQUEST_CODE);
}

之后,我会在Uri中获取用户选择的文档的onActivityResult,并将其传递给压缩所选文档的AsyncTask

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        if (data != null) {
            dialog = new ProgressDialog(getActivity());
            dialog.setMessage(getString(R.string.upload_dialog));
            dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            dialog.setIndeterminate(true);
            dialog.setCancelable(false);
            dialog.show();

            // The document selected by the user won't be returned in the intent.
            // Instead, a URI to that document will be contained in the return intent
            // provided to this method as a parameter.
            // Pull that URI using resultData.getData().
            new ZipFile().execute(data.getData());
        }
    }
}

以下是我的AsyncTask课程:

private class ZipFile extends AsyncTask<Uri, Void, String> {

    @Override
    protected String doInBackground(Uri... uris) {
        Uri uri = uris[0];
        String fileName = null;

        try {
            fileName = zm.createPath("user");
            zm.zipFromUri(uri, fileName, commonMethods.getFileName(uri));
        } catch (NullPointerException | IOException e) {
            e.printStackTrace();
        }
        return fileName;
    }

    @Override
    protected void onPostExecute(String fileName) {
        dialog.dismiss();
        if (fileName != null) {
            renderView(view);
        }
    }
}

renderView功能中,我会显示一个小吃栏并更新我的片段的UI。

private void renderView(View view) {

    CoordinatorLayout fileSnackbarView = view.findViewById(R.id.filesCoordinatorLayout);

    //Exception at this line
    fileSnackbar = Snackbar.make(fileSnackbarView, String.format(getResources().getString(R.string.snackbarMessage), FILE_COUNT), Snackbar.LENGTH_INDEFINITE)
            .setAction(getResources().getString(R.string.snackbarAction), new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(getActivity(), ViewSelectedFilesActivity.class);
                    Bundle bundle = new Bundle();
                    ArrayList<String> selectedFileName = new ArrayList<>();
                    selectedFileName.add(commonMethods.getFromPreferences(Constants.originalFileNameKey, "string"));
                    bundle.putStringArrayList("fileList", selectedFileName);
                    intent.putExtras(bundle);
                    startActivity(intent);
                }
            });
    ... code        
}

但是,我的应用程序因异常Fragment not attached to a context而崩溃。下面是完整的堆栈跟踪:

03-08 12:09:20.647 11490-11490/com.zeetim.zeeprintmobile.android E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.zeetim.zeeprintmobile.android, PID: 11490
java.lang.IllegalStateException: Fragment HomeFragment{674af0} not attached to a context.
    at android.support.v4.app.Fragment.requireContext(Fragment.java:611)
    at android.support.v4.app.Fragment.getResources(Fragment.java:675)
    at com.zeetim.zeeprintmobile.fragment.HomeFragment.renderView(HomeFragment.java:287)
    at com.zeetim.zeeprintmobile.fragment.HomeFragment.access$700(HomeFragment.java:51)
    at com.zeetim.zeeprintmobile.fragment.HomeFragment$ZipFile.onPostExecute(HomeFragment.java:595)
    at com.zeetim.zeeprintmobile.fragment.HomeFragment$ZipFile.onPostExecute(HomeFragment.java:563)
    at android.os.AsyncTask.finish(AsyncTask.java:695)
    at android.os.AsyncTask.-wrap1(Unknown Source:0)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

在某些调试中,我发现isAdded()返回falsegetActivity()getContext()null

流程似乎很直接,但它不起作用。那么我有什么遗漏吗? 如何从onPostExecute调用的onActivityResult更新我的片段的用户界面?

谢谢。

2 个答案:

答案 0 :(得分:0)

onPostExecute

中试试
   new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {

           //if(isAdded()) {
            if (fileName != null) {
                renderView(view);
            }
         }

       // }
    },300);

答案 1 :(得分:0)

各种各样的黑客:

由于你的代码传递了这个:

CoordinatorLayout fileSnackbarView = view.findViewById(R.id.filesCoordinatorLayout);

您可以使用视图访问资源:

view.getContext().getResources()代替getResources()

真正的问题是你的HomeFragment与活动失去联系。

我不认为错误在您提供的代码中。更有可能:

  • 您的活动出现了错误(虽然我对此表示怀疑)
  • 你的片段发生了错误(更像是它)

可能是在doInBackground期间,您的代码的另一部分会将您的片段替换为另一部分,或将其删除。