在我的应用程序中,我在按钮上单击以启动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()
返回false
和getActivity()
,getContext()
为null
。
流程似乎很直接,但它不起作用。那么我有什么遗漏吗?
如何从onPostExecute
调用的onActivityResult
更新我的片段的用户界面?
谢谢。
答案 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
期间,您的代码的另一部分会将您的片段替换为另一部分,或将其删除。