这一行看着简单,但里面藏着几个新手容易懵的点。我把它拆开讲。
先看这个点是啥
android:name=".MyApplication"前面那个.很多人第一眼看不懂。它不是打错了,也不是省略号,它代表包名。
啥意思呢?你的项目肯定有个包名,比如com.example.myapp,就是那个每个类文件顶上写的package com.example.myapp。
那个点,就是这个包名的简写。所以:
android:name=".MyApplication"完整写出来其实是:
android:name="com.example.myapp.MyApplication"系统看到开头是个点,就知道"哦,前面把包名省了,我自己补上"。两种写法效果一样,但第一种省事,大家都这么写。
它指向的是一个类
这里要强调一个之前提过的点:android:name后面跟的不是资源,是一个类。
别看它也带个点,就以为跟@mipmap/ic_launcher那些是一类。完全两码事:
@mipmap/xxx—— 去 res 文件夹找资源.MyApplication—— 指向你写的一个 Java/Kotlin 类
所以.MyApplication对应的,是你项目里一个真实存在的类文件,大概长这样:
packagecom.example.myapp;publicclassMyApplicationextendsApplication{// ...}如果你 Manifest 里写了.MyApplication,但项目里根本没这个类,App 一启动就崩。
这个类是干啥的
重点来了。<application>标签的android:name,指定的是一个自定义 Application 类。
这里得先搞清楚一个概念:每个 App 运行时,系统都会自动创建一个 Application 对象。
这个对象有啥特点?
- 它是整个 App 里最先被创建的
- 它活得最久,从 App 启动到关闭一直都在
- 整个 App只有一个它
如果你不写android:name,系统就用默认的 Application 类,你也感觉不到它的存在。
但如果你想在 App 启动的一开始就干点事,就得自己写一个类去继承 Application,然后在 Manifest 里通过android:name告诉系统:“别用默认的了,用我这个。”
一般拿它来干嘛
最典型的用途就是全局初始化。
举个实际的场景。你 App 里接了一堆第三方 SDK,比如推送、统计、崩溃收集啥的,这些东西通常都要求你在 App 一启动就初始化好。
那放哪初始化呢?就放在自定义 Application 的onCreate里:
publicclassMyApplicationextendsApplication{@OverridepublicvoidonCreate(){super.onCreate();// App 一启动就执行这里,全局初始化都塞这推送SDK.init(this);统计SDK.init(this);崩溃收集.init(this);}}因为 Application 是最先创建的,把初始化放这,能保证后面任何界面用到这些 SDK 时,它们都已经准备好了。
除了初始化,还常拿它存全局共享的数据——因为整个 App 就一个 Application 对象,走到哪它都在,放里面的数据谁都能拿到。
完整走一遍流程
串起来看就是这样:
第一步,你写个类继承 Application:
packagecom.example.myapp;publicclassMyApplicationextendsApplication{@OverridepublicvoidonCreate(){super.onCreate();// 初始化的活儿放这}}第二步,在 Manifest 里登记:
<applicationandroid:name=".MyApplication"...>第三步,App 启动时,系统看到这行,就会创建你这个MyApplication而不是默认的,然后自动调用它的onCreate。
你的初始化代码,就在这一刻执行了。
几个容易踩的坑
坑一:类路径写错。
.MyApplication里的类名必须和你实际写的类对得上,包名也得对。写错了 App 直接崩,而且报错信息有时不太直观,容易找半天。
坑二:把它当资源引用。
前面说过了,它是类,不是@那种资源,别搞混。
坑三:不写也没事,别硬加。
如果你的 App 压根没有全局初始化的需求,其实可以不写android:name,用系统默认的就行。别为了写而写,专门整个空的 Application 类放那也没意义。
小结
一句话概括:android:name=".MyApplication"就是告诉系统,别用默认的 Application 了,用我自己写的那个,好让我在 App 启动时抢先做点全局初始化的事。
那个开头的点是包名的简写,后面跟的是类,不是资源。搞清这两点,这行代码就没啥神秘的了。