pakcage install 过程分析
1.调用安装的接口有两个。
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
installPackage(packageURI, observer, flags, null);
}
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags,
final String installerPackageName);
可以看到第一个接口直接调用了第二个接口,只是最后一个参数传了null。
下面解释一下每个参数:
packageURI:apk文件的Uri。
observer:从名字可以看出, IPackageInstallObserver,是为了监听安装完成以后的监听器。需要创建一个IPackageInstallObserver对象传进来,监听安装结果,最后会给出一个完整的安装例子。
flags:安装的一些标志,比如是否覆盖安装等,这些标志在PackageManager中有常量标示。
installerPackageName:为调用安装接口的调用者,可以为null。
2.installPackage()的实现很简单,首先通过mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);来判断一下,时候申请了INSTALL_PACKAGES的权限。
然后通过:
Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI, observer, flags,
installerPackageName);
mHandler.sendMessage(msg);
向handler传递一个INIT_COPY的消息和InstallParams对象。
3.handler处理INIT_COPY消息。首先判断是否已经DefaultContainerConnection获取到。如果获取失败,调用InstallParams的serviceError()进行错误处理。如果获取到,就将此次安装添加到ArrayList<HandlerParams> mPendingInstalls = new ArrayList<HandlerParams>();这个安装队列中。添加完成后,如果是第一个添加到队列中的安装,就通过handler发送MCS_BOUND消息来启动安装。
4.handler处理MCS_BOUND消息。判断mPendingInstalls是否为空,不为空的话,就取得队列中的第一个安装,并且调用InstallParam的父类HandlerParams的startCopy()来进行安装。
5.startCopy()会handleStartCopy()。handleStartCopy首先会check flag的各个域。然后会生成一个InstallArgs对象,调用copyApk(mContainerService, true);
6.handleStartCopy()调用结束后,handler发送MCS_UNBIND消息。
7.handler处理MCS_UNBIND消息,首先会从mPendingInstalls安装队列中清除第一个item。然后判断mPendingInstalls是否为空,如果为空,则断开DefaultContainerConnection连接,如果不为空,则继续通过handler发送MCS_BOUND消息来启动下一个安装。
1.调用安装的接口有两个。
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
installPackage(packageURI, observer, flags, null);
}
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags,
final String installerPackageName);
可以看到第一个接口直接调用了第二个接口,只是最后一个参数传了null。
下面解释一下每个参数:
packageURI:apk文件的Uri。
observer:从名字可以看出, IPackageInstallObserver,是为了监听安装完成以后的监听器。需要创建一个IPackageInstallObserver对象传进来,监听安装结果,最后会给出一个完整的安装例子。
flags:安装的一些标志,比如是否覆盖安装等,这些标志在PackageManager中有常量标示。
installerPackageName:为调用安装接口的调用者,可以为null。
2.installPackage()的实现很简单,首先通过mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);来判断一下,时候申请了INSTALL_PACKAGES的权限。
然后通过:
Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI, observer, flags,
installerPackageName);
mHandler.sendMessage(msg);
向handler传递一个INIT_COPY的消息和InstallParams对象。
3.handler处理INIT_COPY消息。首先判断是否已经DefaultContainerConnection获取到。如果获取失败,调用InstallParams的serviceError()进行错误处理。如果获取到,就将此次安装添加到ArrayList<HandlerParams> mPendingInstalls = new ArrayList<HandlerParams>();这个安装队列中。添加完成后,如果是第一个添加到队列中的安装,就通过handler发送MCS_BOUND消息来启动安装。
4.handler处理MCS_BOUND消息。判断mPendingInstalls是否为空,不为空的话,就取得队列中的第一个安装,并且调用InstallParam的父类HandlerParams的startCopy()来进行安装。
5.startCopy()会handleStartCopy()。handleStartCopy首先会check flag的各个域。然后会生成一个InstallArgs对象,调用copyApk(mContainerService, true);
6.handleStartCopy()调用结束后,handler发送MCS_UNBIND消息。
7.handler处理MCS_UNBIND消息,首先会从mPendingInstalls安装队列中清除第一个item。然后判断mPendingInstalls是否为空,如果为空,则断开DefaultContainerConnection连接,如果不为空,则继续通过handler发送MCS_BOUND消息来启动下一个安装。