在应用App的代码中调用如下代码:
 

context.getExternalFilesDir("");

这段代码,会在主动创建目录:./Android/data/包名/files;

我们来一下这个调用栈:

buildPaths:934, Environment (android.os)buildExternalStorageAppFilesDirs:131, Environment$UserEnvironment (android.os)buildExternalStorageAppFilesDirs:686, Environment (android.os)getExternalFilesDirs:633, ContextImpl (android.app)getExternalFilesDir:626, ContextImpl (android.app)getExternalFilesDir:242, ContextWrapper (android.content)getFile:98, MainActivity (cn.rocky)access$100:25, MainActivity (cn.rocky)handleMessage:83, MainActivity$1 (cn.rocky)dispatchMessage:106, Handler (android.os)loop:164, Looper (android.os)main:6548, ActivityThread (android.app)invoke:-1, Method (java.lang.reflect)run:438, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)main:857, ZygoteInit (com.android.internal.os)

这些代码一个来分析一下:
frameworks/base/core/java/android/content/Context.java

public abstract File getExternalFilesDir(@Nullable String type);

上面的实现代码:frameworks/base/core/java/android/app/ContextImpl.java

        @Override    public File getExternalFilesDir(String type) {        // Operates on primary external storage        final File[] dirs = getExternalFilesDirs(type);        return (dirs != null && dirs.length > 0) ? dirs[0] : null;    }    @Override    public File[] getExternalFilesDirs(String type) {        synchronized (mSync) {            File[] dirs = Environment.buildExternalStorageAppFilesDirs(getPackageName());            if (type != null) {                dirs = Environment.buildPaths(dirs, type);            }            return ensureExternalDirsExistOrFilter(dirs);        }    }    /**     * Ensure that given directories exist, trying to create them if missing. If     * unable to create, they are filtered by replacing with {@code null}.     */    private File[] ensureExternalDirsExistOrFilter(File[] dirs) {        File[] result = new File[dirs.length];        for (int i = 0; i < dirs.length; i++) {            File dir = dirs[i];            if (!dir.exists()) {//判断目录是否存在,如果不存在,走if                if (!dir.mkdirs()) {//创建目录,创建目录失败,走if,否则走else                    // recheck existence in case of cross-process race                    if (!dir.exists()) {//再次判断目录是否存在,不存在,走if,通过binder服务来创建目录,因为可能是权限不够导致                        // Failing to mkdir() may be okay, since we might not have                        // enough permissions; ask vold to create on our behalf.                        final IStorageManager storageManager = IStorageManager.Stub.asInterface(                                ServiceManager.getService("mount"));                        try {                            final int res = storageManager.mkdirs(                                    getPackageName(), dir.getAbsolutePath());                            if (res != 0) {                                Log.w(TAG, "Failed to ensure " + dir + ": " + res);                                dir = null;                            }                        } catch (Exception e) {                            Log.w(TAG, "Failed to ensure " + dir + ": " + e);                            dir = null;                        }                    }                }            }            result[i] = dir;        }        return result;    }

frameworks/base/core/java/android/os/Environment.java

    public static final String DIR_ANDROID = "Android";    private static final String DIR_DATA = "data";    private static final String DIR_OBB = "obb";    private static final String DIR_FILES = "files";    /**     * Generates the path to an application's files.     * @hide     */    public static File[] buildExternalStorageAppFilesDirs(String packageName) {        throwIfUserRequired();        return sCurrentUser.buildExternalStorageAppFilesDirs(packageName);    }    /**     * Append path segments to each given base path, returning result.     *     * @hide     */    public static File[] buildPaths(File[] base, String... segments) {        File[] result = new File[base.length];        for (int i = 0; i < base.length; i++) {            result[i] = buildPath(base[i], segments);        }        return result;    }    /**     * Append path segments to given base path, returning result.     *  循环创建目录结构     * @hide     */    public static File buildPath(File base, String... segments) {        File cur = base;        for (String segment : segments) {            if (cur == null) {                cur = new File(segment);            } else {                cur = new File(cur, segment);            }        }        return cur;    }    /** {@hide} */    public static class UserEnvironment {        //获取外部的盘符根目录        public File[] getExternalDirs() {            final StorageVolume[] volumes = StorageManager.getVolumeList(mUserId,                    StorageManager.FLAG_FOR_WRITE);            final File[] files = new File[volumes.length];            for (int i = 0; i < volumes.length; i++) {                files[i] = volumes[i].getPathFile();            }            return files;        }        //构造目录结构        public File[] buildExternalStorageAppFilesDirs(String packageName) {            return buildPaths(getExternalDirs(), DIR_ANDROID, DIR_DATA, packageName, DIR_FILES);        }    }

 

这里的代码比较简单,至此,所有挂载的盘符都已经了对应用的Android/data/包名/files目录;

 

 

 

更多相关文章

  1. SVN问题之——org.apache.subversion.javahl.ClientException: A
  2. Android(安卓)proguard -applymapping 导致编译错误
  3. android JNI入门 之helloworld
  4. Android(安卓)逐帧动画创建实例详解
  5. android 目录下三种尺寸的 drawable 文件夹
  6. Android安装常见错误解决办法
  7. 《第一行代码》学习笔记 第 3 章
  8. Android(安卓)失去焦点,关闭弹出的软键盘
  9. Android(安卓)Studio中的跨进程访问(aidl)

随机推荐

  1. 在MAC OS下设置ANDROID_HOME
  2. Android Material Design之TextInputLayo
  3. android recyclerview adaper封装
  4. android popwindow仿微信右上角弹出框,dia
  5. Android(安卓)客户端通过内置API(HttpClie
  6. android开发新浪微博客户端
  7. Android 手绘 - 支持保存为图片
  8. Android常用控件之ExpandableList的使用
  9. Windows Mobile 和 Android(安卓)对比分
  10. Activity 属性设置大全