APK 安装过程 及 原理 详解

APK为AndroidPackage的缩写

Android应用安装有如下四种方式:

1.系统应用安装――开机时完成,没有安装界面

2.网络下载应用安装――通过market应用完成,没有安装界面

3.ADB工具安装――没有安装界面。

4.第三方应用安装――通过SD卡里的APK文件安装,有安装界面,由 packageinstaller.apk 应用处理安装及卸载。

-------------------------------------

应用安装涉及到如下几个目录:        

system/app ---------------系统自带的应用程序,获得adb root权限才能删除

data/app  ---------------用户程序安装的目录。用户 安装时把apk文件 复制 到此目录
data/data ---------------存放应用程序的数据
data/dalvik-cache--------将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)

安装过程:

复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录。

卸载过程:

删除 安装过程中在上述三个目录下创建的文件及目录。

-------------------------

安装应用的过程解析

一.开机安装 
PackageManagerService处理各种 应用的安装,卸载,管理等工作,开机时 由systemServer启动此服务

(源文件路径:android\frameworks\base\services\java\com\android\server\PackageManagerService.java)

PackageManagerService服务 启动的流程:

1.首先 扫描安装“system\framework”目录下的jar包

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="com">// Find base frameworks (resource packages without code).</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            mFrameworkInstallObserver = new AppDirObserver(</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                mFrameworkDir.getPath(), OBSERVER_EVENTS, true);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            mFrameworkInstallObserver.startWatching();</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    | PackageParser.PARSE_IS_SYSTEM_DIR,</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    scanMode | SCAN_NO_DEX, 0);</span></span></p>

2.扫描 安装系统system/app的应用程序

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">  </span><span class="com">// Collect all system packages.</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            mSystemAppDir = new File(Environment.getRootDirectory(), "app");</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            mSystemInstallObserver = new AppDirObserver(</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                mSystemAppDir.getPath(), OBSERVER_EVENTS, true);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            mSystemInstallObserver.startWatching();</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);</span></span></p>

3.制造商的目录下/vendor/app应用包

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="com">// Collect all vendor packages.</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            mVendorAppDir = new File("/vendor/app");</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            mVendorInstallObserver = new AppDirObserver(</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                mVendorAppDir.getPath(), OBSERVER_EVENTS, true);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            mVendorInstallObserver.startWatching();</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);</span></span></p>

4.扫描“data\app”目录,即用户安装的第三方应用

<p><strong>scanDirLI</strong><span class="pun">(</span><span class="pln">mAppInstallDir</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> scanMode</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span></p>

5.扫描" data\app-private"目录,即安装DRM保护的APK文件(一个受保护的歌曲或受保 护的视频是使用 DRM 保护的文件)

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span class="pln">scanDirLI</span><span class="pun">(</span><span class="pln">mDrmAppPrivateInstallDir</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PackageParser</span><span class="pun">.</span><span class="pln">PARSE_FORWARD_LOCK</span><span class="pun">,</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span class="pln">                    scanMode</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span></span></p>

扫描方法的代码清单

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> scanDirLI</span><span class="pun">(</span><span class="typ">File</span><span class="pln"> dir</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> flags</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> scanMode</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> currentTime</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="typ">String</span><span class="pun">[]</span><span class="pln"> files </span><span class="pun">=</span><span class="pln"> dir</span><span class="pun">.</span><span class="pln">list</span><span class="pun">();</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">files </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="typ">Log</span><span class="pun">.</span><span class="pln">d</span><span class="pun">(</span><span class="pln">TAG</span><span class="pun">,</span><span class="pln"> </span><span class="str">"No files in app dir "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> dir</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="kwd">return</span><span class="pun">;</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="pun">}</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">false</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="typ">Log</span><span class="pun">.</span><span class="pln">d</span><span class="pun">(</span><span class="pln">TAG</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Scanning app dir "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> dir</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="pun">}</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> i</span><span class="pun">;</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="pln">i</span><span class="pun">=</span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i</span><span class="pun"><</span><span class="pln">files</span><span class="pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="typ">File</span><span class="pln"> file </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="pln">dir</span><span class="pun">,</span><span class="pln"> files</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">isPackageFilename</span><span class="pun">(</span><span class="pln">files</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]))</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                </span><span class="com">// Ignore entries which are not apk's</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                continue;</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            PackageParser.Package pkg =<strong> scanPackageLI</strong>(file,</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            // Don't mess around with apps in system partition.</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                // Delete the apk</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                Slog.w(TAG, "Cleaning up failed install of " + file);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                file.delete();</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">        }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">    }</span></span></p>

并且从该扫描方法中可以看出调用了scanPackageLI()

private PackageParser.Package scanPackageLI(File scanFile,

int parseFlags, int scanMode, long currentTime)

跟踪scanPackageLI()方法后发现,程序经过很多次的if else 的筛选,最后判定 可以安装apk后,调用了 mInstaller.install

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">mInstaller </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                    </span><span class="kwd">int</span><span class="pln"> ret </span><span class="pun">=</span><span class="pln"> <strong>mInstaller</strong></span><strong><span class="pun">.</span><span class="pln">install</span></strong><span class="pun">(</span><span class="pln">pkgName</span><span class="pun">,</span><span class="pln"> useEncryptedFSDir</span><span class="pun">,</span><span class="pln">  pkg</span><span class="pun">.</span><span class="pln">applicationInfo</span><span class="pun">.</span><span class="pln">uid</span><span class="pun">,</span><span class="pln">pkg</span><span class="pun">.</span><span class="pln">applicationInfo</span><span class="pun">.</span><span class="pln">uid</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                    </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">ret </span><span class="pun"><</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                        </span><span class="com">// Error from installer</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        mLastScanError =    PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        return null;</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                }</span></span></p>

mInstaller.install()  通过    

  LocalSocketAddress address = new LocalSocketAddress(

                "installd", LocalSocketAddress.Namespace.RESERVED);

指挥installd在C语言的文件中完成工作

PackageManagerService小节 :

1)从apk, xml中载入pacakge信息, 存储到内部成员变量中, 用于后面的查找. 关键的方法是scanPackageLI().
2)各种查询操作, 包括query Intent操作.
3)install package和delete package的操作. 还有后面的关键方法是installPackageLI().


二、从网络上下载应用:

下载完成后,会自动调用Packagemanager的安装方法installPackage()

   /* Called when a downloaded package installation has been confirmed by the user */

    由英文注释可见PackageManagerService 类的installPackage()函数为 安装程序 的入口

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> installPackage</span><span class="pun">(</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">Uri</span><span class="pln"> packageURI</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">IPackageInstallObserver</span><span class="pln"> observer</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">final</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> flags</span><span class="pun">,</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> installerPackageName</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        mContext</span><span class="pun">.</span><span class="pln">enforceCallingOrSelfPermission</span><span class="pun">(</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                android</span><span class="pun">.</span><span class="typ">Manifest</span><span class="pun">.</span><span class="pln">permission</span><span class="pun">.</span><span class="pln">INSTALL_PACKAGES</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="typ">Message</span><span class="pln"> msg </span><span class="pun">=</span><span class="pln"> mHandler</span><span class="pun">.</span><span class="pln">obtainMessage</span><span class="pun">(</span><span class="pln">INIT_COPY</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        msg</span><span class="pun">.</span><span class="pln">obj </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">InstallParams</span><span class="pun">(</span><span class="pln">packageURI</span><span class="pun">,</span><span class="pln"> observer</span><span class="pun">,</span><span class="pln"> flags</span><span class="pun">,</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                installerPackageName</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        <strong>mHandler</strong></span><strong><span class="pun">.</span><span class="pln">sendMessage</span></strong><span class="pun">(</span><span class="pln">msg</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">    </span><span class="pun">}</span></span></span></p>

其中是通过PackageHandler的实例mhandler.sendMessage(msg)把信息发给继承Handler的类HandleMessage()方法


<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="kwd">class</span><span class="pln"> </span><span class="typ">PackageHandler</span><span class="pln"> </span><span class="kwd">extends</span><span class="pln"> </span><span class="typ">Handler</span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                 </span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">*****************省略若干********************</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">         </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> handleMessage</span><span class="pun">(</span><span class="typ">Message</span><span class="pln"> msg</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                doHandleMessage</span><span class="pun">(</span><span class="pln">msg</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">finally</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                </span><span class="typ">Process</span><span class="pun">.</span><span class="pln">setThreadPriority</span><span class="pun">(</span><span class="typ">Process</span><span class="pun">.</span><span class="pln">THREAD_PRIORITY_BACKGROUND</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="pun">}</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="pun">}</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">   </span><span class="pun">******************省略若干**********************</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="pun">}</span></span></span></p>

把信息发给doHandleMessage()方法,方法中用switch()语句进行判定传来Message

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="kwd">void</span><span class="pln"> doHandleMessage</span><span class="pun">(</span><span class="typ">Message</span><span class="pln"> msg</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="kwd">switch</span><span class="pln"> </span><span class="pun">(</span><span class="pln">msg</span><span class="pun">.</span><span class="pln">what</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">           </span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                </span><span class="kwd">case</span><span class="pln"> INIT_COPY</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">DEBUG_SD_INSTALL</span><span class="pun">)</span><span class="pln"> </span><span class="typ">Log</span><span class="pun">.</span><span class="pln">i</span><span class="pun">(</span><span class="pln">TAG</span><span class="pun">,</span><span class="pln"> </span><span class="str">"init_copy"</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                    </span><span class="typ">HandlerParams</span><span class="pln"> </span><span class="kwd">params</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">HandlerParams</span><span class="pun">)</span><span class="pln"> msg</span><span class="pun">.</span><span class="pln">obj</span><span class="pun">;</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                    </span><span class="kwd">int</span><span class="pln"> idx </span><span class="pun">=</span><span class="pln"> mPendingInstalls</span><span class="pun">.</span><span class="pln">size</span><span class="pun">();</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">DEBUG_SD_INSTALL</span><span class="pun">)</span><span class="pln"> </span><span class="typ">Log</span><span class="pun">.</span><span class="pln">i</span><span class="pun">(</span><span class="pln">TAG</span><span class="pun">,</span><span class="pln"> </span><span class="str">"idx="</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> idx</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                    </span><span class="com">// If a bind was already initiated we dont really</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    // need to do anything. The pending install</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    // will be processed later on.</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    if (!mBound) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        // If this is the only one pending we might</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        // have to bind to the service again.</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        if (!connectToService()) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            Slog.e(TAG, "Failed to bind to media container service");</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            params.serviceError();</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            return;</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        } else {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            // Once we bind to the service, the first</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            // pending request will be processed.</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            mPendingInstalls.add(idx, params);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    } else {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        mPendingInstalls.add(idx, params);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        // Already bound to the service. Just make</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        // sure we trigger off processing the first request.</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        if (idx == 0) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            mHandler.sendEmptyMessage(MCS_BOUND);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    break;</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                case MCS_BOUND: {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_bound");</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    if (msg.obj != null) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        mContainerService = (IMediaContainerService) msg.obj;</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    if (mContainerService == null) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        // Something seriously wrong. Bail out</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        Slog.e(TAG, "Cannot bind to media container service");</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        for (HandlerParams params : mPendingInstalls) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            mPendingInstalls.remove(0);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            // Indicate service bind error</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            params.serviceError();</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        mPendingInstalls.clear();</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    } else if (mPendingInstalls.size() > 0) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        HandlerParams params = mPendingInstalls.get(0);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        if (params != null) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                            params.startCopy();</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    } else {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        // Should never happen ideally.</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                        Slog.w(TAG, "Empty queue");</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                    break;</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            ****************省略若干**********************</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">}</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">}             </span></span></p>

public final boolean sendMessage (Message msg)

public final boolean sendEmptyMessage (int what)

两者参数有别。

然后调用抽象类HandlerParams中的一个startCopy()方法

abstract class HandlerParams {

final void startCopy() {

   ***************若干if语句判定否这打回handler消息*******

handleReturnCode();

}
}

handleReturnCode()复写了两次其中有一次是删除时要调用的,只列出安装调用的一个方法

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="lit">@Override</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="kwd">void</span><span class="pln"> handleReturnCode</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">            </span><span class="com">// If mArgs is null, then MCS couldn't be reached. When it</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            // reconnects, it will try again to install. At that point, this</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            // will succeed.</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            if (mArgs != null) {</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                processPendingInstall(mArgs, mRet);</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">            }</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">        }</span></span></p>

这时可以清楚的看见 processPendingInstall()被调用。

其中run()方法如下

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">run</span><span class="pun">(){</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="kwd">synchronized</span><span class="pln"> </span><span class="pun">(</span><span class="pln">mInstallLock</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                        </span><span class="pun">************省略*****************</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                        installPackageLI</span><span class="pun">(</span><span class="pln">args</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">,</span><span class="pln"> res</span><span class="pun">);</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">                   </span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="pun">}</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">}</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">instaPacakgeLI</span><span class="pun">()</span><span class="pln">args</span><span class="pun">,</span><span class="pln">res</span><span class="pun">参数分析</span></span></span></p>

-----------------------------------------------------------------------------------------

//InstallArgs 是在PackageService定义的static abstract class InstallArgs 静态抽象类。

<p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="kwd">static</span><span class="pln"> </span><span class="kwd">abstract</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">InstallArgs</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">*********************************************************************</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pun">其中定义了</span><span class="pln">flag</span><span class="pun">标志,</span><span class="pln">packageURL</span><span class="pun">,创建文件,拷贝</span><span class="pln">apk</span><span class="pun">,修改包名称,</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">                    </span><span class="pun">还有一些删除文件的清理,释放存储函数。</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">    </span><span class="pun">*********************************************************************</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;">}</span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">  </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">PackageInstalledInfo</span><span class="pln"> </span><span class="pun">{</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="typ">String</span><span class="pln"> name</span><span class="pun">;</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> uid</span><span class="pun">;</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="typ">PackageParser</span><span class="pun">.</span><span class="typ">Package</span><span class="pln"> pkg</span><span class="pun">;</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> returnCode</span><span class="pun">;</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln">        </span><span class="typ">PackageRemovedInfo</span><span class="pln"> removedInfo</span><span class="pun">;</span></span></span></p><p style="margin-bottom: 0.21cm;"><span style="font-family: Arial;"><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="pun">}</span></span></span></p>

-----------------------------------------------------------------------------------------

<p><span style="font-size: 15px; line-height: 24px;"><span class="pln">  </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> installPackageLI</span><span class="pun">(</span><span class="typ">InstallArgs</span><span class="pln"> args</span><span class="pun">,</span>
<span class="pln">            </span><span class="kwd">boolean</span><span class="pln"> newInstall</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PackageInstalledInfo</span><span class="pln"> res</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">        </span><span class="kwd">int</span><span class="pln"> pFlags </span><span class="pun">=</span><span class="pln"> args</span><span class="pun">.</span><span class="pln">flags</span><span class="pun">;</span>
<span class="pln">        </span><span class="typ">String</span><span class="pln"> installerPackageName </span><span class="pun">=</span><span class="pln"> args</span><span class="pun">.</span><span class="pln">installerPackageName</span><span class="pun">;</span>
<span class="pln">        </span><span class="typ">File</span><span class="pln"> tmpPackageFile </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="pln">args</span><span class="pun">.</span><span class="pln">getCodePath</span><span class="pun">());</span>
<span class="pln">        </span><span class="kwd">boolean</span><span class="pln"> forwardLocked </span><span class="pun">=</span><span class="pln"> </span><span class="pun">((</span><span class="pln">pFlags </span><span class="pun">&</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_FORWARD_LOCK</span><span class="pun">)</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span>
<span class="pln">        </span><span class="kwd">boolean</span><span class="pln"> onSd </span><span class="pun">=</span><span class="pln"> </span><span class="pun">((</span><span class="pln">pFlags </span><span class="pun">&</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_EXTERNAL</span><span class="pun">)</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span>
<span class="pln">        </span><span class="kwd">boolean</span><span class="pln"> replace </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span>
<span class="pln">        </span><span class="kwd">int</span><span class="pln"> scanMode </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">onSd </span><span class="pun">?</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> SCAN_MONITOR</span><span class="pun">)</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> SCAN_FORCE_DEX </span><span class="pun">|</span><span class="pln"> SCAN_UPDATE_SIGNATURE</span>
<span class="pln">                </span><span class="pun">|</span><span class="pln"> </span><span class="pun">(</span><span class="pln">newInstall </span><span class="pun">?</span><span class="pln"> SCAN_NEW_INSTALL </span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span>
<span class="pln">        </span><span class="com">// Result object to be returned</span>
<span class="pln">        res</span><span class="pun">.</span><span class="pln">returnCode </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_SUCCEEDED</span><span class="pun">;</span>
<span class="pln">        </span><span class="com">// Retrieve PackageSettings and parse package</span>
<span class="pln">        </span><span class="kwd">int</span><span class="pln"> parseFlags </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PackageParser</span><span class="pun">.</span><span class="pln">PARSE_CHATTY </span><span class="pun">|</span>
<span class="pln">        </span><span class="pun">(</span><span class="pln">forwardLocked </span><span class="pun">?</span><span class="pln"> </span><span class="typ">PackageParser</span><span class="pun">.</span><span class="pln">PARSE_FORWARD_LOCK </span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">|</span>
<span class="pln">        </span><span class="pun">(</span><span class="pln">onSd </span><span class="pun">?</span><span class="pln"> </span><span class="typ">PackageParser</span><span class="pun">.</span><span class="pln">PARSE_ON_SDCARD </span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span>
<span class="pln">        parseFlags </span><span class="pun">|=</span><span class="pln"> mDefParseFlags</span><span class="pun">;</span>
<span class="pln">        </span><span class="typ">PackageParser</span><span class="pln"> pp </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">PackageParser</span><span class="pun">(</span><span class="pln">tmpPackageFile</span><span class="pun">.</span><span class="pln">getPath</span><span class="pun">());</span>
<span class="pln">        pp</span><span class="pun">.</span><span class="pln">setSeparateProcesses</span><span class="pun">(</span><span class="pln">mSeparateProcesses</span><span class="pun">);</span>
<span class="pln">        </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">PackageParser</span><span class="pun">.</span><span class="typ">Package</span><span class="pln"> pkg </span><span class="pun">=</span><span class="pln"> pp</span><span class="pun">.</span><span class="pln">parsePackage</span><span class="pun">(</span><span class="pln">tmpPackageFile</span><span class="pun">,</span>
<span class="pln">                </span><span class="kwd">null</span><span class="pun">,</span><span class="pln"> mMetrics</span><span class="pun">,</span><span class="pln"> parseFlags</span><span class="pun">);</span>
<span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">pkg </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            res</span><span class="pun">.</span><span class="pln">returnCode </span><span class="pun">=</span><span class="pln"> pp</span><span class="pun">.</span><span class="pln">getParseError</span><span class="pun">();</span>
<span class="pln">            </span><span class="kwd">return</span><span class="pun">;</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="typ">String</span><span class="pln"> pkgName </span><span class="pun">=</span><span class="pln"> res</span><span class="pun">.</span><span class="pln">name </span><span class="pun">=</span><span class="pln"> pkg</span><span class="pun">.</span><span class="pln">packageName</span><span class="pun">;</span>
<span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">((</span><span class="pln">pkg</span><span class="pun">.</span><span class="pln">applicationInfo</span><span class="pun">.</span><span class="pln">flags</span><span class="pun">&</span><span class="typ">ApplicationInfo</span><span class="pun">.</span><span class="pln">FLAG_TEST_ONLY</span><span class="pun">)</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">((</span><span class="pln">pFlags</span><span class="pun">&</span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_ALLOW_TEST</span><span class="pun">)</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                res</span><span class="pun">.</span><span class="pln">returnCode </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_FAILED_TEST_ONLY</span><span class="pun">;</span>
<span class="pln">                </span><span class="kwd">return</span><span class="pun">;</span>
<span class="pln">            </span><span class="pun">}</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">GET_CERTIFICATES </span><span class="pun">&&</span><span class="pln"> </span><span class="pun">!</span><span class="pln">pp</span><span class="pun">.</span><span class="pln">collectCertificates</span><span class="pun">(</span><span class="pln">pkg</span><span class="pun">,</span><span class="pln"> parseFlags</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            res</span><span class="pun">.</span><span class="pln">returnCode </span><span class="pun">=</span><span class="pln"> pp</span><span class="pun">.</span><span class="pln">getParseError</span><span class="pun">();</span>
<span class="pln">            </span><span class="kwd">return</span><span class="pun">;</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="com">// Get rid of all references to package scan path via parser.</span>
<span class="pln">        pp </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span>
<span class="pln">        </span><span class="typ">String</span><span class="pln"> oldCodePath </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span>
<span class="pln">        </span><span class="kwd">boolean</span><span class="pln"> systemApp </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span>
<span class="pln">        </span><span class="kwd">synchronized</span><span class="pln"> </span><span class="pun">(</span><span class="pln">mPackages</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            </span><span class="com">// Check if installing already existing package</span>
<span class="pln">            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">((</span><span class="pln">pFlags</span><span class="pun">&</span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_REPLACE_EXISTING</span><span class="pun">)</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                </span><span class="typ">String</span><span class="pln"> oldName </span><span class="pun">=</span><span class="pln"> mSettings</span><span class="pun">.</span><span class="pln">mRenamedPackages</span><span class="pun">.</span><span class="kwd">get</span><span class="pun">(</span><span class="pln">pkgName</span><span class="pun">);</span>
<span class="pln">                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">pkg</span><span class="pun">.</span><span class="pln">mOriginalPackages </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span>
<span class="pln">                        </span><span class="pun">&&</span><span class="pln"> pkg</span><span class="pun">.</span><span class="pln">mOriginalPackages</span><span class="pun">.</span><span class="pln">contains</span><span class="pun">(</span><span class="pln">oldName</span><span class="pun">)</span>
<span class="pln">                        </span><span class="pun">&&</span><span class="pln"> mPackages</span><span class="pun">.</span><span class="pln">containsKey</span><span class="pun">(</span><span class="pln">oldName</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                    </span><span class="com">// This package is derived from an original package,</span>
<span class="pln">                    </span><span class="com">// and this device has been updating from that original</span>
<span class="pln">                    </span><span class="com">// name.  We must continue using the original name, so</span>
<span class="pln">                    </span><span class="com">// rename the new package here.</span>
<span class="pln">                    pkg</span><span class="pun">.</span><span class="pln">setPackageName</span><span class="pun">(</span><span class="pln">oldName</span><span class="pun">);</span>
<span class="pln">                    pkgName </span><span class="pun">=</span><span class="pln"> pkg</span><span class="pun">.</span><span class="pln">packageName</span><span class="pun">;</span>
<span class="pln">                    replace </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span>
<span class="pln">                </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">mPackages</span><span class="pun">.</span><span class="pln">containsKey</span><span class="pun">(</span><span class="pln">pkgName</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                    </span><span class="com">// This package, under its official name, already exists</span>
<span class="pln">                    </span><span class="com">// on the device; we should replace it.</span>
<span class="pln">                    replace </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span>
<span class="pln">                </span><span class="pun">}</span>
<span class="pln">            </span><span class="pun">}</span>
<span class="pln">            </span><span class="typ">PackageSetting</span><span class="pln"> ps </span><span class="pun">=</span><span class="pln"> mSettings</span><span class="pun">.</span><span class="pln">mPackages</span><span class="pun">.</span><span class="kwd">get</span><span class="pun">(</span><span class="pln">pkgName</span><span class="pun">);</span>
<span class="pln">            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">ps </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                oldCodePath </span><span class="pun">=</span><span class="pln"> mSettings</span><span class="pun">.</span><span class="pln">mPackages</span><span class="pun">.</span><span class="kwd">get</span><span class="pun">(</span><span class="pln">pkgName</span><span class="pun">).</span><span class="pln">codePathString</span><span class="pun">;</span>
<span class="pln">                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">ps</span><span class="pun">.</span><span class="pln">pkg </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pln"> </span><span class="pun">&&</span><span class="pln"> ps</span><span class="pun">.</span><span class="pln">pkg</span><span class="pun">.</span><span class="pln">applicationInfo </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                    systemApp </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">ps</span><span class="pun">.</span><span class="pln">pkg</span><span class="pun">.</span><span class="pln">applicationInfo</span><span class="pun">.</span><span class="pln">flags </span><span class="pun">&</span>
<span class="pln">                            </span><span class="typ">ApplicationInfo</span><span class="pun">.</span><span class="pln">FLAG_SYSTEM</span><span class="pun">)</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span>
<span class="pln">                </span><span class="pun">}</span>
<span class="pln">            </span><span class="pun">}</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">systemApp </span><span class="pun">&&</span><span class="pln"> onSd</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            </span><span class="com">// Disable updates to system apps on sdcard</span>
<span class="pln">            </span><span class="typ">Slog</span><span class="pun">.</span><span class="pln">w</span><span class="pun">(</span><span class="pln">TAG</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Cannot install updates to system apps on sdcard"</span><span class="pun">);</span>
<span class="pln">            res</span><span class="pun">.</span><span class="pln">returnCode </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_FAILED_INVALID_INSTALL_LOCATION</span><span class="pun">;</span>
<span class="pln">            </span><span class="kwd">return</span><span class="pun">;</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">args</span><span class="pun">.</span><span class="pln">doRename</span><span class="pun">(</span><span class="pln">res</span><span class="pun">.</span><span class="pln">returnCode</span><span class="pun">,</span><span class="pln"> pkgName</span><span class="pun">,</span><span class="pln"> oldCodePath</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            res</span><span class="pun">.</span><span class="pln">returnCode </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_FAILED_INSUFFICIENT_STORAGE</span><span class="pun">;</span>
<span class="pln">            </span><span class="kwd">return</span><span class="pun">;</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="com">// Set application objects path explicitly after the rename</span>
<span class="pln">        setApplicationInfoPaths</span><span class="pun">(</span><span class="pln">pkg</span><span class="pun">,</span><span class="pln"> args</span><span class="pun">.</span><span class="pln">getCodePath</span><span class="pun">(),</span><span class="pln"> args</span><span class="pun">.</span><span class="pln">getResourcePath</span><span class="pun">());</span>
<span class="pln">        pkg</span><span class="pun">.</span><span class="pln">applicationInfo</span><span class="pun">.</span><span class="pln">nativeLibraryDir </span><span class="pun">=</span><span class="pln"> args</span><span class="pun">.</span><span class="pln">getNativeLibraryPath</span><span class="pun">();</span>
<span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">replace</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            replacePackageLI</span><span class="pun">(</span><span class="pln">pkg</span><span class="pun">,</span><span class="pln"> parseFlags</span><span class="pun">,</span><span class="pln"> scanMode</span><span class="pun">,</span>
<span class="pln">                    installerPackageName</span><span class="pun">,</span><span class="pln"> res</span><span class="pun">);</span>
<span class="pln">        </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            installNewPackageLI</span><span class="pun">(</span><span class="pln">pkg</span><span class="pun">,</span><span class="pln"> parseFlags</span><span class="pun">,</span><span class="pln"> scanMode</span><span class="pun">,</span>
<span class="pln">                    installerPackageName</span><span class="pun">,</span><span class="pln">res</span><span class="pun">);</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">    </span><span class="pun">}</span></span></p>

最后判断 如果以前 不存在 那么调用installNewPackageLI()

<p><span style="font-size: 15px; line-height: 24px;"><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> installNewPackageLI</span><span class="pun">(</span><span class="typ">PackageParser</span><span class="pun">.</span><span class="typ">Package</span><span class="pln"> pkg</span><span class="pun">,</span>
<span class="pln">            </span><span class="kwd">int</span><span class="pln"> parseFlags</span><span class="pun">,</span><span class="kwd">int</span><span class="pln"> scanMode</span><span class="pun">,</span>
<span class="pln">            </span><span class="typ">String</span><span class="pln"> installerPackageName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PackageInstalledInfo</span><span class="pln"> res</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">     </span><span class="pun">***********************省略若干*************************************************</span>
<span class="pln">        </span><span class="typ">PackageParser</span><span class="pun">.</span><span class="typ">Package</span><span class="pln"> newPackage </span><span class="pun">=</span><span class="pln"> <strong>scanPackageLI</strong></span><span class="pun">(</span><span class="pln">pkg</span><span class="pun">,</span><span class="pln"> parseFlags</span><span class="pun">,</span><span class="pln"> scanMode</span><span class="pun">,</span>
<span class="pln">               </span><span class="typ">System</span><span class="pun">.</span><span class="pln">currentTimeMillis</span><span class="pun">());</span>
<span class="pln">     </span><span class="pun">***********************省略若干**************************************************</span><span class="pln">  </span>
<span class="pun">}</span></span></p>

最后终于 回到了和 开机安装 一样的地方. 与开机方式安装 调用统一方法。

三、从ADB工具安装 

其 入口函数 源文件为pm.java 

(源文件路径:android\frameworks\base\cmds\pm\src\com\android\commands\pm\Pm.java)

其中\system\framework\pm.jar 包管理库

包管理脚本 \system\bin\pm 解析

Pm.java 文件里的 showUsage就是使用方法

<p><span style="font-size: 15px; line-height: 24px;"><span class="kwd">private</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> showUsage</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"usage: pm [list|path|install|uninstall]"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm list packages [-f]"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm list permission-groups"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm list permissions [-g] [-f] [-d] [-u] [GROUP]"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm list instrumentation [-f] [TARGET-PACKAGE]"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm list features"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm path PACKAGE"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm uninstall [-k] PACKAGE"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm enable PACKAGE_OR_COMPONENT"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm disable PACKAGE_OR_COMPONENT"</span><span class="pun">);</span><span class="pln"> </span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"       pm setInstallLocation [0/auto] [1/internal] [2/external]"</span><span class="pun">);</span>
<span class="pln">      </span><span class="pun">**********************省略**************************</span>
<span class="pln">   </span><span class="pun">}</span></span></p>

安装时候 会调用 runInstall()方法

<p><span style="font-size: 15px; line-height: 24px;"><span class="pln">  </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> runInstall</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">        </span><span class="kwd">int</span><span class="pln"> installFlags </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span>
<span class="pln">        </span><span class="typ">String</span><span class="pln"> installerPackageName </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span>
<span class="pln">        </span><span class="typ">String</span><span class="pln"> opt</span><span class="pun">;</span>
<span class="pln">        </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">((</span><span class="pln">opt</span><span class="pun">=</span><span class="pln">nextOption</span><span class="pun">())</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">opt</span><span class="pun">.</span><span class="pln">equals</span><span class="pun">(</span><span class="str">"-l"</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                installFlags </span><span class="pun">|=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_FORWARD_LOCK</span><span class="pun">;</span>
<span class="pln">            </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">opt</span><span class="pun">.</span><span class="pln">equals</span><span class="pun">(</span><span class="str">"-r"</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                installFlags </span><span class="pun">|=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_REPLACE_EXISTING</span><span class="pun">;</span>
<span class="pln">            </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">opt</span><span class="pun">.</span><span class="pln">equals</span><span class="pun">(</span><span class="str">"-i"</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                installerPackageName </span><span class="pun">=</span><span class="pln"> nextOptionData</span><span class="pun">();</span>
<span class="pln">                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">installerPackageName </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                    </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Error: no value specified for -i"</span><span class="pun">);</span>
<span class="pln">                    showUsage</span><span class="pun">();</span>
<span class="pln">                    </span><span class="kwd">return</span><span class="pun">;</span>
<span class="pln">                </span><span class="pun">}</span>
<span class="pln">            </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">opt</span><span class="pun">.</span><span class="pln">equals</span><span class="pun">(</span><span class="str">"-t"</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                installFlags </span><span class="pun">|=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_ALLOW_TEST</span><span class="pun">;</span>
<span class="pln">            </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">opt</span><span class="pun">.</span><span class="pln">equals</span><span class="pun">(</span><span class="str">"-s"</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                </span><span class="com">// Override if -s option is specified.</span>
<span class="pln">                installFlags </span><span class="pun">|=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_EXTERNAL</span><span class="pun">;</span>
<span class="pln">            </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">opt</span><span class="pun">.</span><span class="pln">equals</span><span class="pun">(</span><span class="str">"-f"</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                </span><span class="com">// Override if -s option is specified.</span>
<span class="pln">                installFlags </span><span class="pun">|=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_INTERNAL</span><span class="pun">;</span>
<span class="pln">            </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Error: Unknown option: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> opt</span><span class="pun">);</span>
<span class="pln">                showUsage</span><span class="pun">();</span>
<span class="pln">                </span><span class="kwd">return</span><span class="pun">;</span>
<span class="pln">            </span><span class="pun">}</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="typ">String</span><span class="pln"> apkFilePath </span><span class="pun">=</span><span class="pln"> nextArg</span><span class="pun">();</span>
<span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"\tpkg: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> apkFilePath</span><span class="pun">);</span>
<span class="pln">        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">apkFilePath </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Error: no package specified"</span><span class="pun">);</span>
<span class="pln">            showUsage</span><span class="pun">();</span>
<span class="pln">            </span><span class="kwd">return</span><span class="pun">;</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><strong><span class="typ">PackageInstallObserver</span></strong><span class="pln"><strong> </strong>obs </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">PackageInstallObserver</span><span class="pun">();</span>
<span class="pln">        </span><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            mPm</span><span class="pun">.</span><span class="pln">installPackage</span><span class="pun">(</span><span class="typ">Uri</span><span class="pun">.</span><span class="pln">fromFile</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="pln">apkFilePath</span><span class="pun">)),</span><span class="pln"> obs</span><span class="pun">,</span><span class="pln"> installFlags</span><span class="pun">,</span>
<span class="pln">                    installerPackageName</span><span class="pun">);</span>
<span class="pln">            </span><span class="kwd">synchronized</span><span class="pln"> </span><span class="pun">(</span><span class="pln">obs</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">obs</span><span class="pun">.</span><span class="pln">finished</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                    </span><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                        obs</span><span class="pun">.</span><span class="pln">wait</span><span class="pun">();</span>
<span class="pln">                    </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="typ">InterruptedException</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                    </span><span class="pun">}</span>
<span class="pln">                </span><span class="pun">}</span>
<span class="pln">                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">obs</span><span class="pun">.</span><span class="pln">result </span><span class="pun">==</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_SUCCEEDED</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                    </span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Success"</span><span class="pun">);</span>
<span class="pln">                </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                    </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Failure ["</span>
<span class="pln">                            </span><span class="pun">+</span><span class="pln"> installFailureToString</span><span class="pun">(</span><span class="pln">obs</span><span class="pun">.</span><span class="pln">result</span><span class="pun">)</span>
<span class="pln">                            </span><span class="pun">+</span><span class="pln"> </span><span class="str">"]"</span><span class="pun">);</span>
<span class="pln">                </span><span class="pun">}</span>
<span class="pln">            </span><span class="pun">}</span>
<span class="pln">        </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="typ">RemoteException</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">e</span><span class="pun">.</span><span class="pln">toString</span><span class="pun">());</span>
<span class="pln">            </span><span class="typ">System</span><span class="pun">.</span><span class="pln">err</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">PM_NOT_RUNNING_ERR</span><span class="pun">);</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">    </span><span class="pun">}</span></span></p>

其中   

PackageInstallObserver obs = new PackageInstallObserver();  

            mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags,

                    installerPackageName);

如果 安装成功

obs.result == PackageManager.INSTALL_SUCCEEDED)

又因为有

IPackageManage mPm;

        mPm = IpackageManager.Stub.asInterface(ServiceManager.getService("package"));

Stub是接口IPackageManage的静态抽象类,asInterface是返回IPackageManager代理的静态方法。

因为class PackageManagerService extends IPackageManager.Stub

所以mPm.installPackage 调用 

    /* Called when a downloaded package installation has been confirmed by the user */

    public void installPackage(

            final Uri packageURI, final IPackageInstallObserver observer, final int flags,final String installerPackageName) 

样  最后 就是 相当于 调用  从网络下载安装 入口了。


四,从SD卡安装

系统调用 PackageInstallerActivity.java

源码路径:android/packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java

进入这个Activity会判断信息是否有错,然后调用

      private void initiateInstall() 判断 是否 曾经有过 同名包的安装,或者包已经安装

通过后 执行private void startInstallConfirm() 点击OK按钮后经过一系列的安装信息的判断 Intent跳转到

<p><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><strong><span class="typ">InstallAppProgress</span><span class="pln"> </span></strong><span class="kwd">extends</span><span class="pln"> </span><span class="typ">Activity</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><span class="typ">View</span><span class="pun">.</span><span class="typ">OnClickListener</span><span class="pun">,</span><span class="pln"> </span><span class="typ">OnCancelListener</span>
<span class="pln">   </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> onCreate</span><span class="pun">(</span><span class="typ">Bundle</span><span class="pln"> icicle</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">        </span><span class="kwd">super</span><span class="pun">.</span><span class="pln">onCreate</span><span class="pun">(</span><span class="pln">icicle</span><span class="pun">);</span>
<span class="pln">        </span><span class="typ">Intent</span><span class="pln"> intent </span><span class="pun">=</span><span class="pln"> getIntent</span><span class="pun">();</span>
<span class="pln">        mAppInfo </span><span class="pun">=</span><span class="pln"> intent</span><span class="pun">.</span><span class="pln">getParcelableExtra</span><span class="pun">(</span><span class="typ">PackageUtil</span><span class="pun">.</span><span class="pln">INTENT_ATTR_APPLICATION_INFO</span><span class="pun">);</span>
<span class="pln">        mPackageURI </span><span class="pun">=</span><span class="pln"> intent</span><span class="pun">.</span><span class="pln">getData</span><span class="pun">();</span>
<span class="pln">        <strong>initView</strong></span><span class="pun">();</span>
<span class="pln">    </span><span class="pun">}</span></p>

方法中调用了initView()方法

<p><span style="font-size: 15px; line-height: 24px;"><span class="pln"> </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> initView</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">        requestWindowFeature</span><span class="pun">(</span><span class="typ">Window</span><span class="pun">.</span><span class="pln">FEATURE_NO_TITLE</span><span class="pun">);</span>
<span class="pln">        setContentView</span><span class="pun">(</span><span class="pln">R</span><span class="pun">.</span><span class="pln">layout</span><span class="pun">.</span><span class="pln">op_progress</span><span class="pun">);</span>
<span class="pln">        </span><span class="kwd">int</span><span class="pln"> installFlags </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span>
<span class="pln">        </span><span class="typ">PackageManager</span><span class="pln"> pm </span><span class="pun">=</span><span class="pln"> getPackageManager</span><span class="pun">();</span>
<span class="pln">        </span><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            </span><span class="typ">PackageInfo</span><span class="pln"> pi </span><span class="pun">=</span><span class="pln"> pm</span><span class="pun">.</span><span class="pln">getPackageInfo</span><span class="pun">(</span><span class="pln">mAppInfo</span><span class="pun">.</span><span class="pln">packageName</span><span class="pun">,</span><span class="pln"> </span>
<span class="pln">                    </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">GET_UNINSTALLED_PACKAGES</span><span class="pun">);</span>
<span class="pln">            </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">pi </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">                installFlags </span><span class="pun">|=</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_REPLACE_EXISTING</span><span class="pun">;</span>
<span class="pln">            </span><span class="pun">}</span>
<span class="pln">        </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="typ">NameNotFoundException</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="kwd">if</span><span class="pun">((</span><span class="pln">installFlags </span><span class="pun">&</span><span class="pln"> </span><span class="typ">PackageManager</span><span class="pun">.</span><span class="pln">INSTALL_REPLACE_EXISTING </span><span class="pun">)!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span>
<span class="pln">            </span><span class="typ">Log</span><span class="pun">.</span><span class="pln">w</span><span class="pun">(</span><span class="pln">TAG</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Replacing package:"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> mAppInfo</span><span class="pun">.</span><span class="pln">packageName</span><span class="pun">);</span>
<span class="pln">        </span><span class="pun">}</span>
<span class="pln">        </span><span class="typ">PackageUtil</span><span class="pun">.</span><span class="typ">AppSnippet</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PackageUtil</span><span class="pun">.</span><span class="pln">getAppSnippet</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">,</span><span class="pln"> mAppInfo</span><span class="pun">,</span>
<span class="pln">                mPackageURI</span><span class="pun">);</span>
<span class="pln">        mLabel </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">as</span><span class="pun">.</span><span class="pln">label</span><span class="pun">;</span>
<span class="pln">        </span><span class="typ">PackageUtil</span><span class="pun">.</span><span class="pln">initSnippetForNewApp</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">as</span><span class="pun">,</span><span class="pln"> R</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">app_snippet</span><span class="pun">);</span>
<span class="pln">        mStatusTextView </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">TextView</span><span class="pun">)</span><span class="pln">findViewById</span><span class="pun">(</span><span class="pln">R</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">center_text</span><span class="pun">);</span>
<span class="pln">        mStatusTextView</span><span class="pun">.</span><span class="pln">setText</span><span class="pun">(</span><span class="pln">R</span><span class="pun">.</span><span class="kwd">string</span><span class="pun">.</span><span class="pln">installing</span><span class="pun">);</span>
<span class="pln">        mProgressBar </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">ProgressBar</span><span class="pun">)</span><span class="pln"> findViewById</span><span class="pun">(</span><span class="pln">R</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">progress_bar</span><span class="pun">);</span>
<span class="pln">        mProgressBar</span><span class="pun">.</span><span class="pln">setIndeterminate</span><span class="pun">(</span><span class="kwd">true</span><span class="pun">);</span>
<span class="pln">        </span><span class="com">// Hide button till progress is being displayed</span>
<span class="pln">        mOkPanel </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">View</span><span class="pun">)</span><span class="pln">findViewById</span><span class="pun">(</span><span class="pln">R</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">buttons_panel</span><span class="pun">);</span>
<span class="pln">        mDoneButton </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Button</span><span class="pun">)</span><span class="pln">findViewById</span><span class="pun">(</span><span class="pln">R</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">done_button</span><span class="pun">);</span>
<span class="pln">        mLaunchButton </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Button</span><span class="pun">)</span><span class="pln">findViewById</span><span class="pun">(</span><span class="pln">R</span><span class="pun">.</span><span class="pln">id</span><span class="pun">.</span><span class="pln">launch_button</span><span class="pun">);</span>
<span class="pln">        mOkPanel</span><span class="pun">.</span><span class="pln">setVisibility</span><span class="pun">(</span><span class="typ">View</span><span class="pun">.</span><span class="pln">INVISIBLE</span><span class="pun">);</span>
<span class="pln">        </span><span class="typ">String</span><span class="pln"> installerPackageName </span><span class="pun">=</span><span class="pln"> getIntent</span><span class="pun">().</span><span class="pln">getStringExtra</span><span class="pun">(</span>
<span class="pln">                </span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">EXTRA_INSTALLER_PACKAGE_NAME</span><span class="pun">);</span>
<span class="pln">        </span><span class="typ">PackageInstallObserver</span><span class="pln"> observer </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">PackageInstallObserver</span><span class="pun">();</span>
<span class="pln">        pm</span><span class="pun">.</span><span style="color: rgb(255, 0, 0);"><strong><span class="pln">installPackage</span></strong></span><span class="pun">(</span><span class="pln">mPackageURI</span><span class="pun">,</span><span class="pln"> observer</span><span class="pun">,</span><span class="pln"> installFlags</span><span class="pun">,</span><span class="pln"> installerPackageName</span><span class="pun">);</span>
<span class="pln">    </span><span class="pun">}</span></span><span style="font-family: Arial;"><span style="font-size: 15px;">
</span></span></p><div style="font-family: Arial; font-size: 15px;">
</div>


方法最后 我们可以看到 再次调用安装接口 完成安装,相当于 又 调用了 网络安装。


---------------------------------------

总结:

1.系统应用安装――开机时完成

2.网络下载应用安装――最后 会 调用  系统应用安装 的 scanPackageLI 接口;

3.ADB工具安装――最后 会 调用   网络下载应用安装 的installPackage 接口,从而 相当于 走的 还是系统应用安装 的 路径;

4.第三方应用安装――由 packageinstaller.apk 应用处理安装及卸载,最后也会 调用   网络下载应用安装installPackage 接口,从而 相当于 走的 还是系统应用安装 的 路径。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值