刚学 Android 那会儿我盯着 AndroidManifest.xml 里这几行看了半天applicationandroid:name.MyApplicationandroid:iconmipmap/ic_launcherandroid:labelstring/app_nameandroid:themestyle/AppTheme/application其他还好理解就那个mipmap/ic_launcher让我很困惑。它长得像个路径但又不太像。而且我更纳闷的是——就写这么一句话App 图标怎么就自己冒出来了后来搞明白了这篇就把当时踩过的坑和想通的点记下来。先破除一个误会我一开始以为mipmap/ic_launcher是文件路径类似/mipmap/ic_launcher.png这种。其实不是。它是 Android 的资源引用。你可以把它理解成一个代号而不是文件的实际位置。格式很简单资源类型/资源名字套进去看—— 告诉系统接下来是个资源引用mipmap—— 资源的类型ic_launcher—— 资源的名字所以这句话翻译过来就是“帮我找到 mipmap 里那个叫 ic_launcher 的东西”。它不关心文件具体在哪只给系统一个名字让系统自己去找。那资源到底放哪了虽然写法上不是路径但文件肯定是真实存在的。它们都躺在项目的res文件夹里res/ ├── mipmap-hdpi/ │ └── ic_launcher.png ├── mipmap-xhdpi/ │ └── ic_launcher.png ├── mipmap-xxhdpi/ │ └── ic_launcher.png ├── values/ │ ├── strings.xml ← string 从这找 │ └── themes.xml ← style 从这找你注意到没ic_launcher.png这个图标不止一份好几个文件夹里都有后缀不一样hdpi、xhdpi、xxhdpi。这些代表不同的屏幕清晰度。这就引出了下一个问题。为啥写一句话就能加载出图标这块是我当时最想不通的。后来分三步理解就顺了。第一步编译的时候系统会扫一遍 res 文件夹。它给每个资源都编个号记在一个叫R.java的文件里这文件是自动生成的不用你管。大概长这样publicfinalclassR{publicstaticfinalclassmipmap{publicstaticfinalintic_launcher0x7f0e0000;}}你看ic_launcher被分配了一个数字编号0x7f0e0000。第二步你写的mipmap/ic_launcher会被替换成这个编号。也就是说编译之后那句人类看得懂的引用变成了机器认的数字 ID。第三步App 跑起来的时候系统拿着这个编号去查。查到编号对应的是ic_launcher.png然后根据当前手机的屏幕清晰度从那一堆文件夹里挑一张最合适的加载出来。整个链条就是你写 mipmap/ic_launcher ↓ 编译时 变成数字 ID ↓ 运行时 系统查到对应文件挑合适分辨率的图 ↓ 图标显示出来所以不是写一句话就变出图标中间系统悄悄干了不少活。为什么要搞这么麻烦我也想过直接写死文件路径不就行了干嘛整个引用系统出来。用了一阵子才明白这套东西是真省事。最直接的好处是自动适配屏幕。你就写mipmap/ic_launcher一句系统会根据用户手机的清晰度自己去 hdpi、xhdpi、xxhdpi 里挑最搭的那张。低清屏用小图高清屏用大图你一行代码都不用改。要是让你自己写路径那就麻烦了——你得先判断人家手机什么分辨率再手动选文件光想想就头大。另一个好处是多语言。比如这个android:labelstring/app_name你可以准备两份文字values/strings.xml app_name 我的应用 values-en/strings.xml app_name My App用户手机是中文就显示我的应用是英文就显示My App。你还是那一句引用系统自动帮你切。这种事儿要是手动做代码里得写一堆 if else 判断语言太恶心了。顺带说说 mipmap 和 drawable刚开始我还纳闷图片不都放 drawable 吗图标咋用的 mipmap。简单说mipmap是专门给 App 启动图标用的drawable放其他所有图片。区别在于系统打包的时候可能会精简掉 drawable 里用不上的分辨率但 mipmap 里的会都留着。所以启动图标放 mipmap 更保险。记住一句话就够了图标放 mipmap其他图片放 drawable。一个容易搞混的地方回头看最开始那段代码有个地方要单独拎出来说android:name.MyApplication这个.MyApplication不是资源引用别看它也带个点就以为跟 一类。它是类的路径那个点代表包名。它指向的是你写的一个 Java/Kotlin 类跟 mipmap、string 这些资源完全是两码事。我当时就把这俩搞混过以为 name 也是去 res 里找找了半天没找到纳闷了好久。常见的几种引用用得多了这几种基本天天见mipmap/xxx—— 启动图标drawable/xxx—— 普通图片string/xxx—— 文字color/xxx—— 颜色style/xxx—— 样式layout/xxx—— 布局都是同一个套路类型/名字记住一个其他的自然就会了。最后其实这套资源引用机制核心就一件事你只管用名字去引用剩下的选文件、适配分辨率、切换语言系统全帮你搞定。想通这一点再看那些开头的东西就不慌了。它不是什么神秘路径就是个让系统帮你干活的代号而已。刚学的时候被这些细节卡住很正常我也是查了不少资料加上自己动手试才弄明白的。写下来一是给自己留个记录二是万一有人跟我当初一样困惑希望能帮上点忙。