继续上一篇:PackageManagerService Android 8.1 源码解读 04
这篇主要是讲解apk安装的主要流程代码:
f、点击一个apk后,会弹出【安装界面】,同时显示一个“来历不明的应用......”相关字样的对话框,点击“继续”按钮,执行【PackageInstallerActivity.initiateInstall()】方法;这个方法的主要作用是判断apk是否已经安装
/**
* Dialog to show when the source of apk can not be identified
*/
public static class AnonymousSourceDialog extends DialogFragment {
static AnonymousSourceDialog newInstance() {
return new AnonymousSourceDialog();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setMessage(R.string.anonymous_source_warning)
.setPositiveButton(R.string.anonymous_source_continue,
((dialog, which) -> ((PackageInstallerActivity) getActivity())
.initiateInstall()))
.setNegativeButton(R.string.cancel, ((dialog, which) -> getActivity().finish()))
.create();
}
@Override
public void onCancel(DialogInterface dialog) {
getActivity().finish();
}
}
g、【initiateInstall】继续调用【startInstallConfirm】,这里会更新UI, 根据成员变量:mAppInfo是否为空,来加载不同的UI内容;
private void startInstallConfirm() {
// We might need to show permissions, load layout with permissions
if (mAppInfo != null) {
bindUi(R.layout.install_confirm_perm_update, true);
} else {
bindUi(R.layout.install_confirm_perm, true);
}
.......省略很多代码
}
public void onClick(View v) {
if (v == mOk) {
if (mOk.isEnabled()) {
if (mOkCanInstall || mScrollView == null) {
if (mSessionId != -1) {
mInstaller.setPermissionsResult(mSessionId, true);
finish();
} else {
//点击"安装",进行APK安装
startInstall();
}
} else {
mScrollView.pageScroll(View.FOCUS_DOWN);
}
}
} else if (v == mCancel) {
// Cancel and finish
setResult(RESULT_CANCELED);
if (mSessionId != -1) {
//如果mSessionId存在,执行setPermissionsResult()完成取消安装
mInstaller.setPermissionsResult(mSessionId, false);
}
finish();
}
}
h、【startInstall】方法组装了一个Intent,并跳转到 【InstallInstalling】 这个Activity,并关闭掉当前的
PackageInstallerActivity。InstallInstalling主要用于向包管理器发送包的信息并处理包管理的回调:
private void startInstall() {
// Start subactivity to actually install the application
Intent newIntent = new Intent();
newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
mPkgInfo.applicationInfo);
// 设置包的路径地址:file:///data/user_de/0/com.android.packageinstaller/no_backup/package3012945554531725993.apk
newIntent.setData(mPackageURI);
// 设置目标Activity类:InstallInstalling.class
newIntent.setClass(this, InstallInstalling.class);
//下面就是设置Extra的参数了
String installerPackageName = getIntent().getStringExtra(
Intent.EXTRA_INSTALLER_PACKAGE_NAME);
if (mOriginatingURI != null) {
newIntent.putExtra(Intent.EXTRA_ORIGINATING_URI, mOriginatingURI);
}
if (mReferrerURI != null) {
newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI);
}
if (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) {
newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid);
}
if (installerPackageName != null) {
newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME,
installerPackageName);
}
if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
}
if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);
// 启动新的Activity之后,结束掉当前的PackageInstallerActivity
startActivity(newIntent);
finish();
}
i、启动 InstallInstalling,进入onCreate, 重点是看onCreate函数中的六步:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.install_installing);
ApplicationInfo appInfo = getIntent()
.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
mPackageURI = getIntent().getData();
if ("package".equals(mPackageURI.getScheme())) {
try {// 安装一个已经存在系统的apk
getPackageManager().installExistingPackage(appInfo.packageName);
launchSuccess();
} catch (PackageManager.NameNotFoundException e) {
launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
}
} else {
// 根据mPackageURI创建一个对应的File
final File sourceFile = new File(mPackageURI.getPath());
PackageUtil.initSnippetForNewApp(this, PackageUtil.getAppSnippet(this, appInfo,
sourceFile), R.id.app_snippet);
// 第一步.如果savedInstanceState不为null,获取此前保存的mSessionId和
// mInstallId,其中mSessionId是安装包的会话id,mInstallId是等待的安装事件id
if (savedInstanceState != null) {
mSessionId = savedInstanceState.getInt(SESSION_ID);
mInstallId = savedInstanceState.getInt(INSTALL_ID);
// Reregister for result; might instantly call back if result was delivered while
// activity was destroyed
try {
// 第二步.根据mInstallId向InstallEventReceiver注册一个观察者,
// launchFinishBasedOnResult会接收到安装事件的回调,
// 无论安装成功或者失败都会关闭当前的Activity(InstallInstalling)。如果
// savedInstanceState为null,代码的逻辑也是类似的
InstallEventReceiver.addObserver(this, mInstallId,
this::launchFinishBasedOnResult);
} catch (EventResultPersister.OutOfIdsException e) {
// Does not happen
}
} else {
// 第三步.创建SessionParams,它用来代表安装会话的参数,组装params
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
params.referrerUri = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER);
params.originatingUri = getIntent()
.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
params.originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
UID_UNKNOWN);
// 第四步.根据mPackageUri对包(APK)进行轻量级的解析,并将解析的参数赋值给SessionParams
File file = new File(mPackageURI.getPath());
try {
PackageParser.PackageLite pkg = PackageParser.parsePackageLite(file, 0);
params.setAppPackageName(pkg.packageName);
params.setInstallLocation(pkg.installLocation);
params.setSize(
PackageHelper.calculateInstalledSize(pkg, false, params.abiOverride));
} catch (PackageParser.PackageParserException e) {
Log.e(LOG_TAG, "Cannot parse package " + file + ". Assuming defaults.");
Log.e(LOG_TAG,
"Cannot calculate installed size " + file + ". Try only apk size.");
params.setSize(file.length());
} catch (IOException e) {
Log.e(LOG_TAG,
"Cannot calculate installed size " + file + ". Try only apk size.");
params.setSize(file.length());
}
try {
// 第五步.向InstallEventReceiver注册一个观察者返回一个新的mInstallId,
// 其中InstallEventReceiver继承自BroadcastReceiver,用于接收安装事件并
// 回调给EventResultPersister
mInstallId = InstallEventReceiver
.addObserver(this, EventResultPersister.GENERATE_NEW_ID,
this::launchFinishBasedOnResult);
} catch (EventResultPersister.OutOfIdsException e) {
launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
}
try {
// 第六步.PackageInstaller的createSession方法内部会通过
// IPackageInstaller与PackageInstallerService进行进程间通信,
// 最终调用的是PackageInstallerService的createSession方法来创建并返回
// mSessionId
mSessionId = getPackageManager().getPackageInstaller().createSession(params);
} catch (IOException e) {
launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
}
}
mCancelButton = (Button) findViewById(R.id.cancel_button);
mCancelButton.setOnClickListener(view -> {
if (mInstallingTask != null) {
mInstallingTask.cancel(true);
}
if (mSessionId > 0) {
getPackageManager().getPackageInstaller().abandonSession(mSessionId);
mSessionId = 0;
}
setResult(RESULT_CANCELED);
finish();
});
mSessionCallback = new InstallSessionCallback();
}
}
注意: 以上第六步是重点 PackageInstaller 的 createSession()内部会通过【IPackageInstaller】与【PackageInstallerService】进行进程间通信,最终调用的是【PackageInstallerService】的【createSession】方法来【创建并返回】mSessionId
j、InstallInstalling.onResume方法中,调用onPostExecute()方法,将APK的信息通过IO流的形式写入到PackageInstaller.Session中
@Override
protected void onResume() {
super.onResume();
// This is the first onResume in a single life of the activity
if (mInstallingTask == null) {
// 获取 PackageInstaller 对象,安装器
PackageInstaller installer = getPackageManager().getPackageInstaller();
// 获取sessionInfo
PackageInstaller.SessionInfo sessionInfo = installer.getSessionInfo(mSessionId);
if (sessionInfo != null && !sessionInfo.isActive()) {
// 创建任务InstallingAsyncTask对象,最终调用execute方法
mInstallingTask = new InstallingAsyncTask();
mInstallingTask.execute();
} else {
// we will receive a broadcast when the install is finished
mCancelButton.setEnabled(false);
setFinishOnTouchOutside(false);
}
}
}
k、Installinstalling.InstallingAsyncTask: 关注 第一步 和 第二步
// 第一步: doInBackground()会根据包(APK)的Uri,将APK的信息通过IO流的形式写入到
// PackageInstaller.Session中
@Override
protected PackageInstaller.Session doInBackground(Void... params) {
PackageInstaller.Session session;
try {
session = getPackageManager().getPackageInstaller().openSession(mSessionId);
} catch (IOException e) {
return null;
}
session.setStagingProgress(0);
try {
// 创建apk的文件
File file = new File(mPackageURI.getPath());
// 写数据到服务端
try (InputStream in = new FileInputStream(file)) {
long sizeBytes = file.length();
try (OutputStream out = session
.openWrite("PackageInstaller", 0, sizeBytes)) {
byte[] buffer = new byte[1024 * 1024];
while (true) {
int numRead = in.read(buffer);
if (numRead == -1) {
session.fsync(out);
break;
}
if (isCancelled()) {
session.close();
break;
}
//将APK的信息通过IO流的形式写入到PackageInstaller.Session中
out.write(buffer, 0, numRead);
if (sizeBytes > 0) {
float fraction = ((float) numRead / (float) sizeBytes);
session.addProgress(fraction);
}
}
}
}
return session;
} catch (IOException | SecurityException e) {
Log.e(LOG_TAG, "Could not write package", e);
session.close();
return null;
} finally {
synchronized (this) {
isDone = true;
notifyAll();
}
}
}
// 第二步:最后在onPostExecute()中 调用PackageInstaller.Session的commit方法,进行安装
@Override
protected void onPostExecute(PackageInstaller.Session session) {
if (session != null) {
Intent broadcastIntent = new Intent(BROADCAST_ACTION);
broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
broadcastIntent.setPackage(
getPackageManager().getPermissionControllerPackageName());
broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mInstallId);
// 组装 PendingIntent对象
PendingIntent pendingIntent = PendingIntent.getBroadcast(
InstallInstalling.this,
mInstallId,
broadcastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// 调用PackageInstaller.Session的commit方法,进行安装
session.commit(pendingIntent.getIntentSender());
mCancelButton.setEnabled(false);
setFinishOnTouchOutside(false);
} else {
getPackageManager().getPackageInstaller().abandonSession(mSessionId);
if (!isCancelled()) {
launchFailure(PackageManager.INSTALL_FAILED_INVALID_APK, null);
}
}
}
l、PackageInstaller的commit()方法;
public static class Session implements Closeable {
private IPackageInstallerSession mSession;
public void commit(@NonNull IntentSender statusReceiver) {
try {
// 通过IPackageInstallerSession来进行进程间的通信,最终会调用
// PackageInstallerSession的commit方法,这样代码逻辑就到了Java框架层的。
mSession.commit(statusReceiver, false);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
m、PackageInstallerSession.commit()中,IPackageInstallerSession.aidl接口被PackageInstallerSession继承
// PackageInstallerSession.java类的 commit()
@Override
public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
Preconditions.checkNotNull(statusReceiver);
.......
// 【注意】向Handler发送一个类型为MSG_COMMIT的消息 ,下面会分析
mCommitted = true;
mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
.......
}
MSG_COMMIT在handler中进行处理,进入commitLocked()方法,这个方法比较代码比较多
// PackageInstallerSession.java类
private final PackageManagerService mPm;
private void commitLocked()
throws PackageManagerException {
.......省略代码
mRelinquished = true;
// 最终调用installStage(),进入PKMG
mPm.installStage(mPackageName, stageDir, stageCid, localObserver, params,
mInstallerPackageName, mInstallerUid, user, mCertificates);
}
n、最终调用 mPm.installStage(),进入PKMS 【经过千辛万苦,终于要进入PKMS了】
void installStage(String packageName, File stagedDir, String stagedCid,
IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
String installerPackageName, int installerUid, UserHandle user,
Certificate[][] certificates) {
.......省略代码
// 第一步.创建了类型为INIT_COPY的消息
final Message msg = mHandler.obtainMessage(INIT_COPY);
final int installReason = fixUpInstallReason(installerPackageName, installerUid,
sessionParams.installReason);
// 第二步.创建InstallParams,它对应于包的安装数据
final InstallParams params = new InstallParams(origin, null, observer,
sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
verificationInfo, user, sessionParams.abiOverride,
sessionParams.grantedRuntimePermissions, certificates, installReason);
params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
System.identityHashCode(msg.obj));
Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
System.identityHashCode(msg.obj));
// 第三步.将InstallParams通过消息发送出去。
mHandler.sendMessage(msg);
}
void doHandleMessage(Message msg) {
switch (msg.what) {
case INIT_COPY: {
HandlerParams params = (HandlerParams) msg.obj;
// 获取挂起的apk安装个数
int idx = mPendingInstalls.size();
// 判断是否绑定com.android.defcontainer/.DefaultContainerService服务;
// 如果没有绑定,进入if体,否则进入else
if (!mBound) {
// 连接服务
if (!connectToService()) {
......
//服务连接失败,直接返回
return;
} else {
// 绑定到服务后,将处理第一个挂起的请求。
mPendingInstalls.add(idx, params);
}
} else {
// 绑定到服务后,将处理第一个挂起的请求。
mPendingInstalls.add(idx, params);
if (idx == 0) {
mHandler.sendEmptyMessage(MCS_BOUND);
}
}
break;
}
........省略代码
}
static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
DEFAULT_CONTAINER_PACKAGE,
"com.android.defcontainer.DefaultContainerService");
//绑定服务:
private boolean connectToService() {
if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
" DefaultContainerService");
Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
if (mContext.bindServiceAsUser(service, mDefContainerConn,
Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
mBound = true;
return true;
}
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return false;
}
o、在服务绑定成功之后,会回调一个函数:
final private DefaultContainerConnection mDefContainerConn =
new DefaultContainerConnection();
// 绑定服务com.android.defcontainer/.DefaultContainerService,
// 回调onServiceConnected方法;
class DefaultContainerConnection implements ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
// IMediaContainerService接口不知道做啥用的
final IMediaContainerService imcs = IMediaContainerService.Stub
.asInterface(Binder.allowBlocking(service));
// 发送MCS_BOUND消息给PackageHandler,绑定成功
mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
}
public void onServiceDisconnected(ComponentName name) {
if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
}
}
case MCS_BOUND: {
if (msg.obj != null) {
// 接受接口对象
mContainerService = (IMediaContainerService) msg.obj;
}
if (mContainerService == null) {
if (!mBound) {//没有绑定成功
......省略,清空安装数据
mPendingInstalls.clear();
} else {//继续等待链接服务
Slog.w(TAG, "Waiting to connect to media container service");
}
} else if (mPendingInstalls.size() > 0) {
HandlerParams params = mPendingInstalls.get(0);
if (params != null) {
// 进入队列开始执行拷贝apk的动作
if (params.startCopy()) {
.........
}
} else {
// Should never happen ideally.
Slog.w(TAG, "Empty queue");
}
break;
}
p、PKMG的主角开始登场,执行startCopy(),拷贝apk
final boolean startCopy() {
boolean res;
try {
if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
if (++mRetries > MAX_RETRIES) {
// 重试,处理错误
mHandler.sendEmptyMessage(MCS_GIVE_UP);
handleServiceError();
return false;
} else {
// 开始处理拷贝
handleStartCopy();
res = true;
}
} catch (RemoteException e) {
if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
mHandler.sendEmptyMessage(MCS_RECONNECT);
res = false;
}
// 处理返回码
handleReturnCode();
return res;
}
q、APK 拷贝 方法调用步骤如下:
PKMS->copyApk()->doCopyApk()->DefaultContainerService->copyPacakge()-->copyPackageInner()->copyFile()
// TODO 通过文件流的操作,把APK拷贝到/data/app等目录
public void handleStartCopy() throws RemoteException {
int ret = PackageManager.INSTALL_SUCCEEDED;
......
final InstallArgs args = createInstallArgs(this);
......
// 拷贝apk
ret = args.copyApk(mContainerService, true);
mRet = ret;
}
//开始拷贝apk
int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
try {
return doCopyApk(imcs, temp);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
if (origin.staged) {
if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
codeFile = origin.file;
resourceFile = origin.file;
return PackageManager.INSTALL_SUCCEEDED;
}
try {
final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
//创建代码文件和资源文件
final File tempDir =
mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
codeFile = tempDir;
resourceFile = tempDir;
} catch (IOException e) {
Slog.w(TAG, "Failed to create copy file: " + e);
return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}
// 新建一个文件描述符,接受数据
final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
@Override
public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
if (!FileUtils.isValidExtFilename(name)) {
throw new IllegalArgumentException("Invalid filename: " + name);
}
try {
final File file = new File(codeFile, name);
final FileDescriptor fd = Os.open(file.getAbsolutePath(),
O_RDWR | O_CREAT, 0644);
Os.chmod(file.getAbsolutePath(), 0644);
return new ParcelFileDescriptor(fd);
} catch (ErrnoException e) {
throw new RemoteException("Failed to open: " + e.getMessage());
}
}
};
int ret = PackageManager.INSTALL_SUCCEEDED;
// 通过服务DefaultContainerService,跨进程拷贝apk包
ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
if (ret != PackageManager.INSTALL_SUCCEEDED) {
Slog.e(TAG, "Failed to copy package");
return ret;
}
final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
NativeLibraryHelper.Handle handle = null;
try {
//拷贝本地库文件
handle = NativeLibraryHelper.Handle.create(codeFile);
ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
abiOverride);
} catch (IOException e) {
Slog.e(TAG, "Copying native libraries failed", e);
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
} finally {
IoUtils.closeQuietly(handle);
}
return ret;
}
r、跨进程调用DefaultContainerService服务的copyPackage()方法;-->copyPackageInner()->copyFile()
@Override
public int copyPackage(String packagePath, IParcelFileDescriptorFactory target) {
if (packagePath == null || target == null) {
return PackageManager.INSTALL_FAILED_INVALID_URI;
}
PackageLite pkg = null;
try {
// 创建包文件
final File packageFile = new File(packagePath);
// 解析包文件
pkg = PackageParser.parsePackageLite(packageFile, 0);
// 内部拷贝包文件
return copyPackageInner(pkg, target);
} catch (PackageParserException | IOException | RemoteException e) {
Slog.w(TAG, "Failed to copy package at " + packagePath + ": " + e);
return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}
}
private int copyPackageInner(PackageLite pkg, IParcelFileDescriptorFactory target)
throws IOException, RemoteException {
// 拷贝文件,命名为"base.apk"
copyFile(pkg.baseCodePath, target, "base.apk");
if (!ArrayUtils.isEmpty(pkg.splitNames)) {
for (int i = 0; i < pkg.splitNames.length; i++) {
copyFile(pkg.splitCodePaths[i], target, "split_" + pkg.splitNames[i] + ".apk");
}
}
return PackageManager.INSTALL_SUCCEEDED;
}
//开始拷贝
private void copyFile(String sourcePath, IParcelFileDescriptorFactory target, String targetName)
throws IOException, RemoteException {
Slog.d(TAG, "Copying " + sourcePath + " to " + targetName);
InputStream in = null;
OutputStream out = null;
try {
// 创建输入输出流,开始拷贝apk
in = new FileInputStream(sourcePath);
out = new ParcelFileDescriptor.AutoCloseOutputStream(
target.open(targetName, ParcelFileDescriptor.MODE_READ_WRITE));
Streams.copy(in, out);
} finally {
IoUtils.closeQuietly(out);
IoUtils.closeQuietly(in);
}
}
s、apk拷贝完成之后,再回调handleReturnCode方法,处理返回码,方法调用processPendingInstall()方法
@Override
void handleReturnCode() {
// If mArgs is null, then MCS couldn't be reached. When it
// reconnects, it will try again to install. At that point, this
// will succeed.
if (mArgs != null) {
// 处理挂起的安装数据
processPendingInstall(mArgs, mRet);
}
}
t、继续走processPendingInstall方法:进入安装apk的核心流程:
private void processPendingInstall(final InstallArgs args, final int currentStatus) {
// 执行一个异步操作,
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
// Result object to be returned
PackageInstalledInfo res = new PackageInstalledInfo();
res.setReturnCode(currentStatus);
res.uid = -1;
res.pkg = null;
res.removedInfo = null;
// 返回码是安装成功的,进入if体
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1.如果之前安装失败,清除无用信息
args.doPreInstall(res.returnCode);
synchronized (mInstallLock) {
// 2. installPackagesTracedLI 是安装过程的核心方法,然后调用
// installPackagesLI 进行安装
installPackageTracedLI(args, res);
}
// 3.如果之前安装失败,清除无用信息
args.doPostInstall(res.returnCode, res.uid);
}
......
}
});
}
private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
// 开始安装apk
installPackageLI(args, res);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
x、installPackageLI方法调用真正的安装方法installNewPackageLIF
private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
.......省略很多代码
try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
"installPackageLI")) {
if (replace) {
if (pkg.applicationInfo.isStaticSharedLibrary()) {
// Static libs have a synthetic package name containing the version
// and cannot be updated as an update would get a new package name,
// unless this is the exact same version code which is useful for
// development.
PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
+ "static-shared libs cannot be updated");
return;
}
}
//替换安装apk
replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
installerPackageName, res, args.installReason);
} else {
// 开始安装新的apk
installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
args.user, installerPackageName, volumeUuid, res, args.installReason);
}
}
.......省略代码
}
/*
* Install a non-existing package.
*/
private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
PackageInstalledInfo res, int installReason) {
.......
try {
// 扫描apk,这个scanPackageTracedLI()方法,之前分析过
PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
System.currentTimeMillis(), user);
// 更新设置信息
updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
// 安装成功,准备app的数据,如果安装失败,移除安装的信息
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
// 重点分析这个方法
prepareAppDataAfterInstallLIF(newPackage);
} else {
// Remove package from internal structures, but keep around any
// data that might have already existed
deletePackageLIF(pkgName, UserHandle.ALL, false, null,
PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
}
} catch (PackageManagerException e) {
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
prepareAppDataAfterInstallLIF方法,通过一系列的调用,最终会调用到[Installer.java] createAppData()进行安装,交给installed进程,进行APK的安装
调用栈如下:
prepareAppDataAfterInstallLIF ->
prepareAppDataLIF ->
prepareAppDataLeafLIF->
mInstaller.createAppData
private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
.......
// 调用Installd守护进程的入口
ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
appId, app.seInfo, app.targetSdkVersion);
........
}
y、Installer.createAppData 收尾工作,安装完成后,更新设置,更新安装锁等:
public long createAppData(String uuid, String packageName, int userId, int flags, int appId,
String seInfo, int targetSdkVersion) throws InstallerException {
if (!checkBeforeRemote()) return -1;
try {
// mInstalld 为IInstalld的对象,即通过Binder调用到 进程installd,最终调用
// installd的createAppData()
// 【注意】 mInstalld是一个aidl文件,通过此aidl文件调用到 Binder机制的服务
// 端,服务端那里要操控底层....
return mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo,
targetSdkVersion);
} catch (Exception e) {
throw InstallerException.from(e);
}
}
z、总结:安装的原理:
APK的安装流程到这里就算完成了;
下一篇将分析 PMS之权限扫描:
PackageManagerService Android 8.1 源码解读 06