解决使用Debug.startMethodTracing后找不到对应的.trace文件
2018-03-23 17:16
459 查看
最近需要分析优化启动时间,查了资料准备使用在方法开始处加Debug.startMethodTracing()结束点加Debug.stopMethodTracing.搜了网上的博客,都是startMethodTracing()不传参数的话默认保存在/sdcard/dmtrace.trace(抄的时候都不去试试,唉) 。 由于懒,执行后直接去执行adb pull 。但是发现根本就没有生成这个文件。迷茫了。。没办法那就看下源码吧,最后还是找到了正解。
就像圈红所述,在第一存储(即内置)包名目录下建立文件。想到了应该是Android/data/目录,然后去找了一下,.trace文件果然在这。坑~。
而且还是用getExternalFilesDir()获取的路径。那就跟进去看下
很长,但是意思是这个文件是根据包名建立的,4.4以后需要在manifest申请读写权限,人而且因为是在包名目录下,卸载后这些文件也将被一起干掉。
type是空的话返回根目录
在ContextImpl具体实现,调用Environment.buildExternalStorageAppFilesDirs
注意这里方框圈里的getExternalFilesDir(type)[0] 拿到的数组第一个位置路径
看下mExternalDirsForApp是什么
Environment初始化的时候拿到所有的路径,先添加内置的emulated,之后添加Secondary_Storage(物理外置卡) 到一个集合ArrayList.最后返回。所以说前面getExternalFilesDir(type)[0] 拿到的是内置SD卡的路径(即storage/emulated/0/…)
这是具体的常量值,刚好是Android/data/包名/files.之后调用buildpath返回路径即最终结果是:storage/emulated/0/Android/data/包名/files/dmtrace.trace
就像圈红所述,在第一存储(即内置)包名目录下建立文件。想到了应该是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. * <p> * This is like {@link #getFilesDir()} in that these files will be deleted * when the application is uninstalled, however there are some important * differences: * <ul> * <li>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)}. * <li>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. * </ul> * <p> * 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. * <p> * 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. * <p> * 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. * <p> * The returned path may change over time if different shared storage media * is inserted, so only relative paths should be persisted. * <p> * Here is an example of typical code to manipulate a file in an * application's shared storage: * </p> * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java * private_file} * <p> * If you supply a non-null <var>type</var> 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. * <p> * Here is an example of typical code to manipulate a picture in an * application's shared stor 4000 age and add it to the media database: * </p> * {@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是空的话返回根目录
源码重点
在ContextImpl具体实现,调用Environment.buildExternalStorageAppFilesDirs
注意这里方框圈里的getExternalFilesDir(type)[0] 拿到的数组第一个位置路径
看下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<File> externalForVold = Lists.newArrayList(); ArrayList<File> 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/…)
这是具体的常量值,刚好是Android/data/包名/files.之后调用buildpath返回路径即最终结果是:storage/emulated/0/Android/data/包名/files/dmtrace.trace
小结
有些事儿还是需要亲力亲为,看了源码就开朗了。可以参看这个文章介绍获取物理外置SD卡路径和读写 点我,求点赞~~~相关文章推荐
- Debug.startMethodTracing Debug.stopMethodTracing TraceView
- Android Debug.startMethodTracing() 报错 Unable to open trace file '/sdcard/*.trace': Permission denied
- 使用CMAKE链接外部的动态库时找不到库文件解决办法(/usr/bin/ld: cannot find lxxx)
- 解决ubuntu 64bit AndroidStudio中的SDK无法使用的问题,提示找不到该文件或目录
- [[NSBundle mainBundle] pathForResource:@"name" ofType:@"type"] 找不到对应的文件解决方法
- Mysql第一次使用-如何解决Mysql "发生系统错误2,找不到指定的文件" 的问题(第一次安装使用)
- 在ARC中使用weak报错和文件目录找不到的解决方法
- Debug.startMethodTracing 去检测程序的性能
- 使用CocoaPods找不到头文件解决方法
- VS 编译提示 无法将“obj\Debug\*.*”复制到“bin\Debug\*.*”,文件...正在由另一个进程使用,因此该进程无法访问此文件 解决办法
- 使用bat文件快速解决adb找不到设备的问题
- 使用CocoaPods找不到头文件解决方法
- 如何解决Mysql "发生系统错误2,找不到指定的文件" 的问题(第一次安装使用)
- VS2010bug 当生成或重新生成时,出现 不能复制文件(从obj\debug到bin\debug),文件正在被另一个进程使用的错误解决办法
- 命令行下使用javah命令生成.h文件,出现“错误: 无法访问android.app.Activity 找不到android.app.Activity的类文件”的解决方法
- 使用LinqDataSource出现“找不到与ViewState中存储的原始值中的给定键相匹配的行,请确保"keys"字典包含与上一个Select操作返回的行对应的唯一键值”错误的解决办法
- 在debug模式下运行不报错,换到release模式下报找不到某某库或文件的错。。解决办法
- 【C/S通信交互之Http篇】使用Curl与Jetty(Server)实现手机网游Http通信框架&解决curl.h头文件找不到问题
- Extjs 使用ajax上传文件,解决Object #<HTMLDivElement> has no method 'submit'
- 使用CocoaPods 但找不到头文件解决方法