众所周知,Android应用最终是打包成.apk格式(其实就是一个压缩包),然后安装至手机并运行的。其中APK是Android Package的缩写。
Android系统在启动的过程中,会启动一个引用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,以.apk为后缀的文件,然后对这些文件进行解析,得到引用程序的相关信息,完成应用程序的安装过程。应用程序管理服务PackageManagerService安装应用程序的过程,其实就是解析应用程序配置文件的AndroidManifest.xml的过程,并从里面得到应用程序的相关信息,例如得到引用程序的组件Activity、Service、Receiver和Content Provider等信息,有了这些信息后,通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。
Android上应用安装可以分为以下几种方式:
apk的大体流程如下:
Android系统中,也有一个类似注册表的东西,用来记录当前所有安装的应用的基本信息,每次系统安装或者卸载了任何apk文件,都会更新这个文件。这个文件位于如下目录:/data/system/packages.xml。系统在安装这个apk的过程中,会解析apk的AndroidManifest.xml文件,提取出这个apk的重要信息写入到packages.xml文件中,这些信息包括:权限、应用包名、APK的安装位置、版本、userID等等。由此,我们就知道了为什么一些应用市场和软件管理类的app能够很清楚地知道当前手机所安装的所有app,以及这些app的详细信息了。另外一件事就是Linux的用户Id和用户组Id,以便他们可以获得合适的运行权限。以上都是由PackageServcieManager完成的,后面我们会重点介绍PackageServiceManager。
PackageInstaller.apk地址
PackageInstaller/AndroidManifest.xml.png
PackagInstaller是安卓上默认的应用程序,用它来安装普通文件。PackageInstaller提供了用户界面来管理应用或者包文件。PackageInstaller调用一个叫做InstallAppProgress的activity来获取用户发出的指令。InstallAppProgress会请求Package Manager服务,然后通过installed来安装包文件。
installed这个守护进程的首要角色就是获取来自Package Manager服务的请求,而该请求是通过Linux套接字/dev/socket/installed获得的。installed使用管理员权限执行一系列步骤来安装APK。
PackageInstaller的结构如下:
PackageInstaller结构1.png
PackageInstaller结构2.png
这里面重点介绍以下两个类
下面我们就来看看
普通的APK安装方式 一般是经过下面的两个界面的
image.png
上面的两个界面分别是PackageInstallerActivity和InstallAppProgress
public class PackageInstallerActivity extends Activity implements OnCancelListener, OnClickListener {
...
...
}
我们是知道PackageInstallerActivity是一个Activity并且实现了OnCancelListener和OnClickListener接口,下面我们来看一下注释。
当通过渠道安装一个应用程序的时候,会启动这个Activity。如果在首次解析这个安装包的时候出现解析错误,会通过对话框的形式告诉用户。如果首次解析安装包的时候,成功解析了,则会通知用户去打开"安装未知应用程序设置"。在启动Activity的时候会进行内存检查,如果内存不足会通知用户。如果这个应用程序已经在这个设备安装过了,则会向用户弹出一个对话框询问用户是否"替换现有应用程序的安装包"。基于用户的回应,然后通过InstallAppConfirm的子Activity来安装应用程序。在这Activity中处理所有状态的转换。
大家平时写Activity一般都是先在onCreate方法里面做一些初始化的操作,那我们来看下PackageInstallerActivity的onCreate里面都做了什么?
代码在PackageInstallerActivity.java 439行
PackageManager mPm;
UserManager mUserManager;
PackageInstaller mInstaller;
PackageInfo mPkgInfo;
ApplicationInfo mSourceInfo;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
//第一步
// 一个PackageManager对象,具体用来执行安装操作
mPm =getPackageManager();
// PackageInstaller对象,在该对象中包含了安装APK的基本信息
mInstaller =mPm.getPackageInstaller();
mUserManager =(UserManager) getSystemService(Context.USER_SERVICE);
// 第二步
final Intent intent =getIntent();
if (PackageInstaller.ACTION_CONFIRM_PERMISSIONS.equals(intent.getAction())) {
final int sessionId =intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1);
final PackageInstaller.SessionInfo info =mInstaller.getSessionInfo(sessionId);
if (info ==null || !info.sealed || info.resolvedBaseCodePath ==null) {
Log.w(TAG, "Session " + mSessionId + " in funky state; ignoring");
finish();
return;
}
mSessionId =sessionId;
mPackageURI =Uri.fromFile(new File(info.resolvedBaseCodePath));
mOriginatingURI =null;
mReferrerURI =null;
} else {
mSessionId =-1;
mPackageURI =intent.getData();
mOriginatingURI =intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
mReferrerURI =intent.getParcelableExtra(Intent.EXTRA_REFERRER);
}
// 第三步
final boolean unknownSourcesAllowedByAdmin =isUnknownSourcesAllowedByAdmin();
final boolean unknownSourcesAllowedByUser =isUnknownSourcesEnabled();
boolean requestFromUnknownSource =isInstallRequestFromUnknownSource(intent);
//第四步
mInstallFlowAnalytics =new InstallFlowAnalytics();
mInstallFlowAnalytics.setContext(this);
mInstallFlowAnalytics.setStartTimestampMillis(SystemClock.elapsedRealtime());
mInstallFlowAnalytics.setInstallsFromUnknownSourcesPermitted(unknownSourcesAllowedByAdmin
&& unknownSourcesAllowedByUser);
mInstallFlowAnalytics.setInstallRequestFromUnknownSource(requestFromUnknownSource);
mInstallFlowAnalytics.setVerifyAppsEnabled(isVerifyAppsEnabled());
mInstallFlowAnalytics.setAppVerifierInstalled(isAppVerifierInstalled());
mInstallFlowAnalytics.setPackageUri(mPackageURI.toString());
//第五步
final String scheme =mPackageURI.getScheme();
if (scheme !=null && !"file".equals(scheme) && !"package".equals(scheme)