解决使用Debug.startMethodTracing后找不到对应的.trace文件

最近需要分析优化启动时间,查了资料准备使用在方法开始处加Debug.startMethodTracing()结束点加Debug.stopMethodTracing.搜了网上的博客,都是startMethodTracing()不传参数的话默认保存在/sdcard/dmtrace.trace(抄的时候都不去试试,唉) 。 由于懒,执行后直接去执行adb pull 。但是发现根本就没有生成这个文件。迷茫了。。没办法那就看下源码吧,最后还是找到了正解。
解决使用Debug.startMethodTracing后找不到对应的.trace文件_第1张图片
就像圈红所述,在第一存储(即内置)包名目录下建立文件。想到了应该是Android/data/目录,然后去找了一下,.trace文件果然在这。坑~。
而且还是用getExternalFilesDir()获取的路径。那就跟进去看下

/**
     * Returns the absolute path to the directory on the primary shared/external
     * storage device where the application can place persistent files it owns.
     * These files are internal to the applications, and not typically visible
     * to the user as media.
     * 

* This is like {@link #getFilesDir()} in that these files will be deleted * when the application is uninstalled, however there are some important * differences: *

    *
  • Shared storage may not always be available, since removable media can * be ejected by the user. Media state can be checked using * {@link Environment#getExternalStorageState(File)}. *
  • There is no security enforced with these files. For example, any * application holding * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to * these files. *
*

* If a shared storage device is emulated (as determined by * {@link Environment#isExternalStorageEmulated(File)}), it's contents are * backed by a private user data partition, which means there is little * benefit to storing data here instead of the private directories returned * by {@link #getFilesDir()}, etc. *

* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions * are required to read or write to the returned path; it's always * accessible to the calling app. This only applies to paths generated for * package name of the calling application. To access paths belonging to * other packages, * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required. *

* On devices with multiple users (as described by {@link UserManager}), * each user has their own isolated shared storage. Applications only have * access to the shared storage for the user they're running as. *

* The returned path may change over time if different shared storage media * is inserted, so only relative paths should be persisted. *

* Here is an example of typical code to manipulate a file in an * application's shared storage: *

* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java * private_file} *

* If you supply a non-null type to this function, the returned * file will be a path to a sub-directory of the given type. Though these * files are not automatically scanned by the media scanner, you can * explicitly add them to the media database with * {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[], android.media.MediaScannerConnection.OnScanCompletedListener) * MediaScannerConnection.scanFile}. Note that this is not the same as * {@link android.os.Environment#getExternalStoragePublicDirectory * Environment.getExternalStoragePublicDirectory()}, which provides * directories of media shared by all applications. The directories returned * here are owned by the application, and their contents will be removed * when the application is uninstalled. Unlike * {@link android.os.Environment#getExternalStoragePublicDirectory * Environment.getExternalStoragePublicDirectory()}, the directory returned * here will be automatically created for you. *

* Here is an example of typical code to manipulate a picture in an * application's shared storage and add it to the media database: *

* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java * private_picture} * * @param type The type of files directory to return. May be {@code null} * for the root of the files directory or one of the following * constants for a subdirectory: * {@link android.os.Environment#DIRECTORY_MUSIC}, * {@link android.os.Environment#DIRECTORY_PODCASTS}, * {@link android.os.Environment#DIRECTORY_RINGTONES}, * {@link android.os.Environment#DIRECTORY_ALARMS}, * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS}, * {@link android.os.Environment#DIRECTORY_PICTURES}, or * {@link android.os.Environment#DIRECTORY_MOVIES}. * @return the absolute path to application-specific directory. May return * {@code null} if shared storage is not currently available. * @see #getFilesDir * @see #getExternalFilesDirs(String) * @see Environment#getExternalStorageState(File) * @see Environment#isExternalStorageEmulated(File) * @see Environment#isExternalStorageRemovable(File) */ @Nullable public abstract File getExternalFilesDir(@Nullable String type);

很长,但是意思是这个文件是根据包名建立的,4.4以后需要在manifest申请读写权限,人而且因为是在包名目录下,卸载后这些文件也将被一起干掉。

The type of files directory to return. May be {@code null}
     *            for the root of the files directory or one of the following
     *            constants for a subdirectory:

type是空的话返回根目录

源码重点

解决使用Debug.startMethodTracing后找不到对应的.trace文件_第2张图片
在ContextImpl具体实现,调用Environment.buildExternalStorageAppFilesDirs
解决使用Debug.startMethodTracing后找不到对应的.trace文件_第3张图片
注意这里方框圈里的getExternalFilesDir(type)[0] 拿到的数组第一个位置路径
解决使用Debug.startMethodTracing后找不到对应的.trace文件_第4张图片
看下mExternalDirsForApp是什么

public UserEnvironment(int userId) {
            // See storage config details at http://source.android.com/tech/storage/
            String rawExternalStorage = System.getenv(ENV_EXTERNAL_STORAGE);
            String rawEmulatedSource = System.getenv(ENV_EMULATED_STORAGE_SOURCE);
            String rawEmulatedTarget = System.getenv(ENV_EMULATED_STORAGE_TARGET);

            String rawMediaStorage = System.getenv(ENV_MEDIA_STORAGE);
            if (TextUtils.isEmpty(rawMediaStorage)) {
                rawMediaStorage = "/data/media";
            }

            ArrayList externalForVold = Lists.newArrayList();
            ArrayList externalForApp = Lists.newArrayList();

            if (!TextUtils.isEmpty(rawEmulatedTarget)) {
                // Device has emulated storage; external storage paths should have
                // userId burned into them.
                final String rawUserId = Integer.toString(userId);
                final File emulatedSourceBase = new File(rawEmulatedSource);
                final File emulatedTargetBase = new File(rawEmulatedTarget);
                final File mediaBase = new File(rawMediaStorage);

                // /storage/emulated/0
                externalForVold.add(buildPath(emulatedSourceBase, rawUserId));
                externalForApp.add(buildPath(emulatedTargetBase, rawUserId));
                // /data/media/0
                mEmulatedDirForDirect = buildPath(mediaBase, rawUserId);

            } else {
                // Device has physical external storage; use plain paths.
                if (TextUtils.isEmpty(rawExternalStorage)) {
                    Log.w(TAG, "EXTERNAL_STORAGE undefined; falling back to default");
                    rawExternalStorage = "/storage/sdcard0";
                }

                // /storage/sdcard0
                externalForVold.add(new File(rawExternalStorage));
                externalForApp.add(new File(rawExternalStorage));
                // /data/media
                mEmulatedDirForDirect = new File(rawMediaStorage);
            }

            // Splice in any secondary storage paths, but only for owner
            final String rawSecondaryStorage = System.getenv(ENV_SECONDARY_STORAGE);
            if (!TextUtils.isEmpty(rawSecondaryStorage) && userId == UserHandle.USER_OWNER) {
                for (String secondaryPath : rawSecondaryStorage.split(":")) {
                    externalForVold.add(new File(secondaryPath));
                    externalForApp.add(new File(secondaryPath));
                }
            }

            mExternalDirsForVold = externalForVold.toArray(new File[externalForVold.size()]);
            mExternalDirsForApp = externalForApp.toArray(new File[externalForApp.size()]);
        }

Environment初始化的时候拿到所有的路径,先添加内置的emulated,之后添加Secondary_Storage(物理外置卡) 到一个集合ArrayList.最后返回。所以说前面getExternalFilesDir(type)[0] 拿到的是内置SD卡的路径(即storage/emulated/0/…)
解决使用Debug.startMethodTracing后找不到对应的.trace文件_第5张图片
这是具体的常量值,刚好是Android/data/包名/files.之后调用buildpath返回路径即最终结果是:storage/emulated/0/Android/data/包名/files/dmtrace.trace

小结

有些事儿还是需要亲力亲为,看了源码就开朗了。可以参看这个文章介绍获取物理外置SD卡路径和读写 点我,求点赞~~~

你可能感兴趣的:(Android,错误,问题小结)