packages/apps/DocumentsUI/res/values-zh-rCN/strings.xml
“获取信息”
packages/apps/DocumentsUI/res/menu/activity.xml
<item
android:id="@+id/option_menu_settings"
android:title="@string/menu_settings"
android:showAsAction="never"
android:visible="false" />
<item
android:id="@+id/option_menu_inspect"
android:title="@string/menu_inspect"
android:showAsAction="never"
android:visible="false" />
</group>
packages/apps/DocumentsUI/src/com/android/documentsui/files/FilesActivity.java
@Override
public boolean onOptionsItemSelected(MenuItem item) {
DirectoryFragment dir;
switch (item.getItemId()) {
case R.id.option_menu_create_dir:
assert(canCreateDirectory());
mInjector.actions.showCreateDirectoryDialog();
break;
case R.id.option_menu_new_window:
mInjector.actions.openInNewWindow(mState.stack);
break;
case R.id.option_menu_settings:
mInjector.actions.openSettings(getCurrentRoot());
break;
case R.id.option_menu_select_all:
mInjector.actions.selectAllFiles();
break;
case R.id.option_menu_inspect:
mInjector.actions.showInspector(getCurrentDirectory());
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
进一步跟踪代码流程:
packages/apps/DocumentsUI/src/com/android/documentsui/files/ActionHandler.java
@Override
public void showInspector(DocumentInfo doc) {
Metrics.logUserAction(mActivity, Metrics.USER_ACTION_INSPECTOR);
Intent intent = new Intent(mActivity, InspectorActivity.class);
intent.setData(doc.derivedUri);
// permit the display of debug info about the file.
intent.putExtra(
Shared.EXTRA_SHOW_DEBUG,
mFeatures.isDebugSupportEnabled() &&
(Build.IS_DEBUGGABLE || DebugFlags.getDocumentDetailsEnabled()));
// The "root document" (top level folder in a root) don't usually have a
// human friendly display name. That's because we've never shown the root
// folder's name to anyone.
// For that reason when the doc being inspected is the root folder,
// we override the displayName of the doc w/ the Root's name instead.
// The Root's name is shown to the user in the sidebar.
if (doc.isDirectory() && mState.stack.size() == 1 && mState.stack.get(0).equals(doc)) {
RootInfo root = mActivity.getCurrentRoot();
// Recents root title isn't defined, but inspector is disabled for recents root folder.
assert !TextUtils.isEmpty(root.title);
intent.putExtra(Intent.EXTRA_TITLE, root.title);
}
mActivity.startActivity(intent);
}
显示对应的信息菜单即为:packages/apps/DocumentsUI/src/com/android/documentsui/files/InspectorActivity.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.inspector_activity);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setActionBar(toolbar);
getActionBar().setDisplayHomeAsUpEnabled(true);
FragmentManager fragmentManager = getFragmentManager();
mFragment = (InspectorFragment) fragmentManager.findFragmentById(
R.id.fragment_container);
if (mFragment == null) {
Intent intent = getIntent();
mFragment = InspectorFragment.newInstance(intent);
fragmentManager.beginTransaction()
.add(R.id.fragment_container, mFragment)
.commit();
}
}
查看代码逻辑可以继续跟进:InspectorFragment.java
根据异常反馈点:
DirectoryLoader.java
@Override
public final DirectoryResult loadInBackground() {
synchronized (this) {
if (isLoadInBackgroundCanceled()) {
throw new OperationCanceledException();
}
mSignal = new CancellationSignal();
}
final ContentResolver resolver = getContext().getContentResolver();
final String authority = mUri.getAuthority();
final DirectoryResult result = new DirectoryResult();
result.doc = mDoc;
ContentProviderClient client = null;
Cursor cursor;
try {
client = DocumentsApplication.acquireUnstableProviderOrThrow(resolver, authority);
if (mDoc.isInArchive()) {
ArchivesProvider.acquireArchive(client, mUri);
}
result.client = client;
Resources resources = getContext().getResources();
if (mFeatures.isContentPagingEnabled()) {
Bundle queryArgs = new Bundle();
mModel.addQuerySortArgs(queryArgs);
// TODO: At some point we don't want forced flags to override real paging...
// and that point is when we have real paging.
DebugFlags.addForcedPagingArgs(queryArgs);
cursor = client.query(mUri, null, queryArgs, mSignal);
} else {
cursor = client.query(
mUri, null, null, null, mModel.getDocumentSortQuery(), mSignal);
}
if (cursor == null) {
throw new RemoteException("Provider returned null");
}
cursor.registerContentObserver(mObserver);
cursor = new RootCursorWrapper(mUri.getAuthority(), mRoot.rootId, cursor, -1);
if (mSearchMode && !mFeatures.isFoldersInSearchResultsEnabled()) {
// There is no findDocumentPath API. Enable filtering on folders in search mode.
cursor = new FilteringCursorWrapper(cursor, null, SEARCH_REJECT_MIMES);
}
// TODO: When API tweaks have landed, use ContentResolver.EXTRA_HONORED_ARGS
// instead of checking directly for ContentResolver.QUERY_ARG_SORT_COLUMNS (won't work)
if (mFeatures.isContentPagingEnabled()
&& cursor.getExtras().containsKey(ContentResolver.QUERY_ARG_SORT_COLUMNS)) {
if (VERBOSE) Log.d(TAG, "Skipping sort of pre-sorted cursor. Booya!");
} else {
cursor = mModel.sortCursor(cursor, mFileTypeLookup);
}
result.cursor = cursor;
} catch (Exception e) {
Log.w(TAG, "Failed to query", e);
result.exception = e;
} finally {
synchronized (this) {
mSignal = null;
}
// TODO: Remove this call.
ContentProviderClient.releaseQuietly(client);
}
return result;
}
再次根据错误信息:
07-13 10:52:33.648 E/Model (11339): Error while loading directory contents
07-13 10:52:33.648 E/Model (11339): java.lang.NullPointerException: Attempt to get length of null array
07-13 10:52:33.648 E/Model (11339): at android.os.Parcel.createException(Parcel.java:1956)
07-13 10:52:33.648 E/Model (11339): at android.os.Parcel.readException(Parcel.java:1918)
07-13 10:52:33.648 E/Model (11339): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
07-13 10:52:33.648 E/Model (11339): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
07-13 10:52:33.648 E/Model (11339): at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
07-13 10:52:33.648 E/Model (11339): at android.content.ContentProviderClient.query(ContentProviderClient.java:163)
07-13 10:52:33.648 E/Model (11339): at com.android.documentsui.DirectoryLoader.loadInBackground(DirectoryLoader.java:125)
07-13 10:52:33.648 E/Model (11339): at com.android.documentsui.DirectoryLoader.loadInBackground(DirectoryLoader.java:51)
07-13 10:52:33.648 E/Model (11339): at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:319)
07-13 10:52:33.648 E/Model (11339): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:73)
07-13 10:52:33.648 E/Model (11339): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:61)
07-13 10:52:33.648 E/Model (11339): at android.os.AsyncTask$2.call(AsyncTask.java:333)
07-13 10:52:33.648 E/Model (11339): at java.util.concurrent.FutureTask.run(FutureTask.java:266)
07-13 10:52:33.648 E/Model (11339): at com.android.documentsui.ProviderExecutor.run(ProviderExecutor.java:104)
packages/apps/DocumentsUI/src/com/android/documentsui/Model.java
protected void update(DirectoryResult result) {
assert(result != null);
if (DEBUG) Log.i(TAG, "Updating model with new result set.");
if (result.exception != null) {
Log.e(TAG, "Error while loading directory contents", result.exception);
reset(); // Resets this model to avoid access to old cursors.
notifyUpdateListeners(result.exception);
return;
}
mCursor = result.cursor;
mCursorCount = mCursor.getCount();
doc = result.doc;
updateModelData();
final Bundle extras = mCursor.getExtras();
if (extras != null) {
info = extras.getString(DocumentsContract.EXTRA_INFO);
error = extras.getString(DocumentsContract.EXTRA_ERROR);
mIsLoading = extras.getBoolean(DocumentsContract.EXTRA_LOADING, false);
}
notifyUpdateListeners();
}
有又错误信息:
07-13 10:52:33.599 W/ActionModeController(11339): Tried to finish a null action mode.
07-13 10:52:33.634 E/DatabaseUtils(11072): Writing exception to parcel
07-13 10:52:33.634 E/DatabaseUtils(11072): java.lang.NullPointerException: Attempt to get length of null array
07-13 10:52:33.634 E/DatabaseUtils(11072): at com.android.internal.content.FileSystemProvider.queryChildDocuments(FileSystemProvider.java:378)
07-13 10:52:33.634 E/DatabaseUtils(11072): at android.provider.DocumentsProvider.queryChildDocuments(DocumentsProvider.java:565)
07-13 10:52:33.634 E/DatabaseUtils(11072): at android.provider.DocumentsProvider.query(DocumentsProvider.java:808)
07-13 10:52:33.634 E/DatabaseUtils(11072): at android.content.ContentProvider$Transport.query(ContentProvider.java:242)
07-13 10:52:33.634 E/DatabaseUtils(11072): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:102)
07-13 10:52:33.634 E/DatabaseUtils(11072): at android.os.Binder.execTransact(Binder.java:731)
找到对应的文件:
packages/apps/DocumentsUI/src/com/android/documentsui/ActionModeController.java
@Override
public void finishActionMode() {
if (mActionMode != null) {
mActionMode.finish();
mActionMode = null;
} else {
Log.w(TAG, "Tried to finish a null action mode.");
}
}
再次回归到错误的log信息:
07-13 10:51:09.372 E/DatabaseUtils(11072): Writing exception to parcel
07-13 10:51:09.372 E/DatabaseUtils(11072): java.lang.NullPointerException: Attempt to get length of null array
07-13 10:51:09.372 E/DatabaseUtils(11072): at com.android.internal.content.FileSystemProvider.queryChildDocuments(FileSystemProvider.java:378)
07-13 10:51:09.372 E/DatabaseUtils(11072): at android.provider.DocumentsProvider.queryChildDocuments(DocumentsProvider.java:565)
07-13 10:51:09.372 E/DatabaseUtils(11072): at android.provider.DocumentsProvider.query(DocumentsProvider.java:808)
07-13 10:51:09.372 E/DatabaseUtils(11072): at android.content.ContentProvider$Transport.query(ContentProvider.java:242)
07-13 10:51:09.372 E/DatabaseUtils(11072): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:102)
07-13 10:51:09.372 E/DatabaseUtils(11072): at android.os.Binder.execTransact(Binder.java:731)
07-13 10:51:09.374 E/AndroidRuntime(11028): FATAL EXCEPTION: AsyncTask #1
07-13 10:51:09.374 E/AndroidRuntime(11028): Process: com.android.documentsui, PID: 11028
07-13 10:51:09.374 E/AndroidRuntime(11028): java.lang.RuntimeException: An error occurred while executing doInBackground()
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.os.AsyncTask$3.done(AsyncTask.java:354)
07-13 10:51:09.374 E/AndroidRuntime(11028): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
07-13 10:51:09.374 E/AndroidRuntime(11028): at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
07-13 10:51:09.374 E/AndroidRuntime(11028): at java.util.concurrent.FutureTask.run(FutureTask.java:271)
07-13 10:51:09.374 E/AndroidRuntime(11028): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
07-13 10:51:09.374 E/AndroidRuntime(11028): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
07-13 10:51:09.374 E/AndroidRuntime(11028): at java.lang.Thread.run(Thread.java:764)
07-13 10:51:09.374 E/AndroidRuntime(11028): Caused by: java.lang.NullPointerException: Attempt to get length of null array
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.os.Parcel.createException(Parcel.java:1956)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.os.Parcel.readException(Parcel.java:1918)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.content.ContentResolver.query(ContentResolver.java:805)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.content.ContentResolver.query(ContentResolver.java:754)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.content.CursorLoader.loadInBackground(CursorLoader.java:68)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.content.CursorLoader.loadInBackground(CursorLoader.java:45)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:319)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:73)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:61)
07-13 10:51:09.374 E/AndroidRuntime(11028): at android.os.AsyncTask$2.call(AsyncTask.java:333)
07-13 10:51:09.374 E/AndroidRuntime(11028): at java.util.concurrent.FutureTask.run(FutureTask.java:266)
07-13 10:51:09.374 E/AndroidRuntime(11028): ... 3 more
07-13 10:51:09.379 W/ActivityManager( 2086): Force finishing activity com.android.documentsui/.inspector.InspectorActivity
可知道,NullPointerException不是报错的根本原因,主要出现应用报错是:doInBackground
由于信息菜单作用也不是很大,暂时先去除吧…