本地安装参与对象包括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下面供虚拟机使用的工程。

更多相关文章

  1. flutter APP 应用名称、启动页、图标配置
  2. Android启动模式需要注意的点
  3. Android(安卓)O media difference(add HIDL)
  4. Android标准调用播放器流程
  5. android linphone中opengl显示的实现
  6. Kivy A to Z -- Android(安卓)apk的生成过程
  7. android 传递自定义参数
  8. android 开发(备忘记录+问题累积)--- 不断更新
  9. Tensorflow:Android调用Tensorflow Mobile版本API(2)-基于Android的

随机推荐

  1. android shape 代码实现按钮背景
  2. 关于 Android(安卓)程序员最近的状况
  3. Android(安卓)Sensor传感器系统架构初探
  4. Pyqtdeploy Android(安卓)PyQtForAndroid
  5. HNU_团队项目_Android和数据库对接出现问
  6. Android(安卓)2011年开发风向标
  7. Android编译系统的架构 简述
  8. Android(安卓)渗透测试学习手册(七)不太知
  9. Android基础笔记(五)-网络编程
  10. [笔记分享] [Android] Android系统概述