8.2.3 启动PackageHandler

进入mPackages同步代码块后执行的第一步操作是启动PackageHandler,其代码如下:


public class PackageManagerService extends IPackageManager.Stub{

……

public PackageManagerService(Context context, boolean factoryTest,

boolean onlyCore){

……

synchronized(mInstallLock){

//writer

synchronized(mPackages){

mHandlerThread.start();//启动Looper线程

//Looper线程的消息循环初始化消息处理器

mHandler=new PackageHandler(mHandlerThread.getLooper());

……

}


在分析PackageHandler之前,先分析其类关系,如图8-6所示。

8.2.3 启动PackageHandler - 图1

图 8-6 PackageHandler类关系

由图8-6表示的类关系可以归纳如下:

PackageManagerService中定义了mHandlerThread和mHandler两个成员变量,其中,mHandlerThread是HandlerThread类型,mHandler是PackageHandler类型。

PackageHandler在构造函数中接收HandlerThread的mLooper成员变量,并将其存入父类Handler的mLooper成员变量中,因此HandlerThread和PackageHandler分别代表了线程消息通信模型的Looper线程和Handler处理器。线程消息通信的内容在第7章详细分析过,这里不赘述。

PackageHandler是PackageManagerService的内部类,继承自Handler,用于接收并处理其他模块程序发送的消息。这些消息可以来自adb或者其他应用程序。

在PackageHandler的handleMessage方法中调用doHandleMessage方法处理消息,代码如下:


public class PackageManagerService extends IPackageManager.Stub{

……

class PackageHandler extends Handler{

void doHandleMessage(Message msg){

switch(msg.what){

case INIT_COPY:{……}

case MCS_BOUND:{……}

case MCS_RECONNECT:{……}

case MCS_UNBIND:{……}

case MCS_GIVE_UP:{……}

case SEND_PENDING_BROADCAST:{……}

case START_CLEANING_PACKAGE:{……}

case POST_INSTALL:{……}

case UPDATED_MEDIA_STATUS:{……}

case WRITE_SETTINGS:{……}

case WRITE_STOPPED_PACKAGES:{……}

case CHECK_PENDING_VERIFICATION:{……}

case PACKAGE_VERIFIED:{……}

……


以上消息主要用于完成APK的复制和更名操作,但这些操作并不是在PackageHandler中完成的,而是需要通过Binder连接MCS服务,通过MCS间接完成。

MCS服务由frameworks/base/packages/DefaultContainerService提供。DefaultContainer Service最终会被编译成DefaultContainerService.apk安装到系统中。

在PackageHandler的消息处理函数中会通过connectToService方法连接该APK文件,代码如下:


public class PackageManagerService extends IPackageManager.Stub{

……

class PackageHandler extends Handler{

……

private boolean connectToService(){

Intent service=new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);

Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);

if(mContext.bindService(service, mDefContainerConn, Context.BIND_AUTO_CREATE)){

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

mBound=true;

return true;

}

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

return false;

}


后续章节将在分析MCS服务的时候详细分析这部分的处理过程。