Android(安卓)PackageManagerService(四)本地安装流程详解
16lz
2021-01-26
本地安装参与对象包括PackageInstaller应用,PMS两部分。下面我们就来分析下PackageInstaller是如何调用到PMS中的。函数调用时序图示。
点击文件管理器里面app文件会启动 PackageInstaller的InstallStart这个activity
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);Intent nextActivity = new Intent(intent);nextActivity.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);nextActivity.putExtra(PackageInstallerActivity.EXTRA_CALLING_PACKAGE, callingPackage);nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINAL_SOURCE_INFO, sourceInfo);nextActivity.putExtra(Intent.EXTRA_ORIGINATING_UID, originatingUid);if (isSessionInstall) {Uri packageUri = intent.getData();if (packageUri != null && (packageUri.getScheme().equals(ContentResolver.SCHEME_FILE)|| packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) {// Copy file to prevent it from being changed underneath this processnextActivity.setClass(this, InstallStaging.class);} }if (nextActivity != null) {startActivity(nextActivity);}finish();}
内部启动 InstallStaging这个 activity,然后在内部onResume方法启动一个任务
@Overrideprotected void onResume() {super.onResume();// This is the first onResume in a single life of the activityif (mStagingTask == null) {// File does not exist, or became invalidif (mStagedFile == null) {// Create file delayed to be able to show errortry {mStagedFile = TemporaryFileManager.getStagedFile(this);} catch (IOException e) {showError();return;}}mStagingTask = new StagingAsyncTask();mStagingTask.execute(getIntent().getData());}}
然后在任务的onPostExecute方法启动PackageInstallerActivity这个activity
@Overrideprotected void onPostExecute(Boolean success) {if (success) {// Now start the installation again from a fileIntent installIntent = new Intent(getIntent());installIntent.setClass(InstallStaging.this, PackageInstallerActivity.class);installIntent.setData(Uri.fromFile(mStagedFile));installIntent.setFlags(installIntent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);installIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);startActivityForResult(installIntent, 0);} else {showError();}}
然后点击安装按钮调用startInstall
public void onClick(View v) { if (v == mOk) { if (mOk.isEnabled()) { if (mOkCanInstall || mScrollView == null) { if (mSessionId != -1) { mInstaller.setPermissionsResult(mSessionId, true); finish(); } else { startInstall(); } } else { mScrollView.pageScroll(View.FOCUS_DOWN); } } } else if (v == mCancel) { // Cancel and finish setResult(RESULT_CANCELED); if (mSessionId != -1) { mInstaller.setPermissionsResult(mSessionId, false); } finish(); } }private void startInstall() { // Start subactivity to actually install the application Intent newIntent = new Intent(); newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mPkgInfo.applicationInfo); newIntent.setData(mPackageURI); newIntent.setClass(this, InstallInstalling.class); 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); startActivity(newIntent); finish(); }
之后启动InstallInstalling,因为Activity中的默认成员方法的执行顺序是onCreate->onStart->onResume...其中onCreate的方法中主要过程包括:
- 1 获取待安装应用信息
- 2 根据应用安装与否决定如何调用方法
- 3 如果已存在,则直接调用PackageManager.installExistingPackage
- 4 如果不存在则构造session
- 5 之后则为安装事件广播添加一个监测
@Overrideprotected 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 { getPackageManager().installExistingPackage(appInfo.packageName); launchSuccess(); } catch (PackageManager.NameNotFoundException e) { launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null); } } else { //否则使用session提交安装应用 final File sourceFile = new File(mPackageURI.getPath()); PackageUtil.initSnippetForNewApp(this, PackageUtil.getAppSnippet(this, appInfo, sourceFile), R.id.app_snippet); // 如果session已存在,则获取sessionId等数据 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 { InstallEventReceiver.addObserver(this, mInstallId, this::launchFinishBasedOnResult); } catch (EventResultPersister.OutOfIdsException e) { // Does not happen } } else { // 否则创建session PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( PackageInstaller.SessionParams.MODE_FULL_INSTALL); // ...... try { mInstallId = InstallEventReceiver .addObserver(this, EventResultPersister.GENERATE_NEW_ID, this::launchFinishBasedOnResult); } catch (EventResultPersister.OutOfIdsException e) { launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null); } //创建session try { mSessionId = getPackageManager().getPackageInstaller().createSession(params); } catch (IOException e) { launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null); } } //...... mSessionCallback = new InstallSessionCallback();
在这个activity里面启动一个任务,然后调用 session.commit(pendingIntent.getIntentSender());
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.getBroadcast( InstallInstalling.this, mInstallId, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT); //提交session session.commit(pendingIntent.getIntentSender()); mCancelButton.setEnabled(false); setFinishOnTouchOutside(false); } else { getPackageManager().getPackageInstaller().abandonSession(mSessionId); if (!isCancelled()) { launchFailure(PackageManager.INSTALL_FAILED_INVALID_APK, null); } } }
session对象传输顺序为:
- PackageInstaller.Session.commit
- IPackageInstallerSession.commit
- PackageInstallerSession.commit
- 4Handler.Callback.handleMessage
- PackageInstallerSession.commitLock
- PMS.installStage
这里是不是似曾相识,这一步跟Adb安装提交session完全一样,之后就调用installStage方法完成安装。
具体参考Android PackageManagerService(三)adb安装流程详解
总结:其实安装的本质就是解析应用,主要是解析Android应用的清单文件,保存到PMS的内部数据结构供系统使用,保存重要信息到package.xml和package.list的配置文件。调用Installd守护进程创建应用数据目录,配置文件,转移dex文件到/data/dalvik-cache下面供虚拟机使用的工程。
更多相关文章
- flutter APP 应用名称、启动页、图标配置
- Android启动模式需要注意的点
- Android(安卓)O media difference(add HIDL)
- Android标准调用播放器流程
- android linphone中opengl显示的实现
- Kivy A to Z -- Android(安卓)apk的生成过程
- android 传递自定义参数
- android 开发(备忘记录+问题累积)--- 不断更新
- Tensorflow:Android调用Tensorflow Mobile版本API(2)-基于Android的