当我安装一个安卓应用程序时,会发生什么?

23

我猜测.apk包的内容会被提取到某个地方,应用程序在某个目录注册,以便应用程序启动器或其他工具可以找到它。但这就是全部吗?如果是这种情况,那么原始的manifest.xml每次启动应用程序时都会读取吗,还是会被预处理成其他形式?

3个回答

39

免责声明:本答案已有10年历史。虽然总体上可能仍然准确,但细节肯定已经发生了变化(ART代替Dalvik、动态与静态权限等)。请谨慎参考!

一些基础知识

.apk文件

.apk文件并不神奇。它只是一个Android应用程序内容的文件束。如果您在存档工具(如7Zip)中打开它,您可以浏览并提取其内容。

Android是Linux

基本的Android系统是一个Linux系统。Android使用带有一些额外功能(如省电和一些速度改进)的自定义Linux内核。Android设备的内部存储器采用YAFFS2文件系统格式化,完全具备类似Linux的访问概念。

所使用的文件系统可能因制造商或Android版本而异。新设备通常使用ext3,而三星则使用自己的文件系统:RFS

这是Android使用的沙盒系统的一个重要方面。

编译应用程序

.java文件会发生什么?

首先,它们由普通的Java编译器编译。编译完成后(生成.class文件),Android SDK中的dx工具将这些“普通”的Java类转换/转译为Dalvik字节码

然后,DVM(Dalvik虚拟机)解释这个“特殊”的Java代码,该虚拟机基于开源JRE实现Apache Harmony

更新:在较新的Android版本中,当使用jack时可以跳过转换/转译步骤。这样,.java文件直接编译成.dx格式。

此外,自4.4版本(KitKat)以来,Android拥有新的ART运行时,它在Android 5(棒棒糖)中正式取代了Dalvik。

我放入/asset目录中的资源会发生什么?

Android提供了/assets目录,用于添加一些二进制原始文件(例如SQLite数据库)。放入该目录的文件不会被编译或优化。

如果您将文件放入此目录,则可以期望Android的这种行为。

我放入/res/raw目录中的资源会发生什么?

/assets目录一样,您也可以在这里放置二进制(或其他)原始文件(例如帮助页面的HTML文件)。这些文件将被编译/优化(如果可能)。

清单文件和其他XML文件会发生什么?

Android清单以及其他XML文件(布局、字符串等)都存储并“编译”为二进制XML格式。这是一种速度优化。

沙箱

从Android操作系统的角度来看,单个应用程序拥有:

  • 它自己的进程,
  • 它自己的OS用户(如Linux),
  • 它自己的DVM,
  • 它自己在堆中的位置和
  • 它自己在文件系统上的位置。

因此,是的,每个Android应用程序都有自己的用户,该用户具有访问其内部存储位置的适当权限(受标准Linux文件系统权限管理的保护),以及它自己的DVM进程(无法从应用程序外部访问)。

为了给应用程序留下离开沙箱的可能性(例如连接到互联网),使用Android清单中声明的权限。

安装过程中的步骤

因此,从上述解释中,应该清楚地了解安装Android应用程序时会发生什么:

  1. 创建了应用程序的新用户。
  2. 使用这个新用户的权限,在内部存储中创建了应用程序目录。
  3. .apk 文件的内容提取到该目录中。
  4. 解析 Android-Manifest,并注册声明的 intent-filter(例如应用程序标准入口点的 android.intent.category.LAUNCHER 过滤器)。
  5. 现在,应用程序已经准备好进行第一次启动。

1
在较新的设备上,使用的是ext3而不是YAFFS。 - Manfred Moser
我没有看到我的.apk文件的任何内容出现在/data/data/{app}/**中。“.apk文件的内容正在那里被提取。” - 有人能告诉我它们确切地被提取到哪里了吗? - Tapemaster
@Tapemaster 我猜这可能取决于您设备的版本/供应商,但在某些时候应该会出现。此外,我不确定是否可以将应用程序安装到SD卡上(而不是安装它并移动)。最后,您的设备是否具有root访问权限?这可能只是因为您的文件浏览器无法访问该文件夹(如果您没有root,则不应该能够访问),因此显示为空目录。 - Lukas Knuth
我有不同类型的设备,包括已经root和未root的设备。对于调试(debuggable)和发布(release)类型的应用程序,我从未注意到资源被提取到/data/data/{app}。你能提供一下你所看到的资源提取的文件结构吗?只需要文件和目录名称即可。 - Tapemaster
@Tapemaster 我发现了这个,它在整个文件系统方面更加详细: https://android.stackexchange.com/questions/46926/android-folder-hierarchy 由于我没有root过我的手机,在我的文件管理器中,/data文件夹看起来是空的。 - Lukas Knuth
显示剩余4条评论

3
当您安装应用程序时,Android系统会将其APK复制到“/data/app”文件夹,并根据包名称和安装次数(您安装或更新应用程序的次数)进行命名。
我尝试通过将其APK复制并粘贴到/data/app文件夹中手动安装一个应用程序,然后重新启动我的设备,它将显示为已安装的应用程序并正常工作。
此外,我注意到在link2SD应用程序中,任何已安装的应用程序都具有以下内容:
APK位于/data/app/package-number.apk
Dex位于/data/dalvik-cache/data@app@package-number.apk@classes.dex
Lib位于/data/data/package/lib
数据位于/data/data/package 缓存位于/data/data/package/cache

1

在编程中,Android 定义意图为“要执行的操作的抽象描述”。通过使用意图不仅可以使用其他人创建的活动,还可以用于启动应用程序。我相信你已经在你编写的每个应用程序中看到了这些行:

<intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

这个意图过滤器允许启动器找到每个应用程序的起始活动。有关此过程的更多详细信息,请查找“意图分辨率”...我认为这比仅在某个随机目录中注册应用程序更优雅。

http://developer.android.com/guide/topics/intents/intents-filters.html所述,“Android系统通过查找所有具有指定“android.intent.action.MAIN”操作和“android.intent.category.LAUNCHER”类别的意图过滤器的活动来填充应用程序启动器,即顶层屏幕,显示用户可以启动的应用程序。然后,在启动器中显示这些活动的图标和标签。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接