8.2.8 启动FileObserver监控APK文件的目录
通过FileObserver对象监控五个存放APK文件的目录。这里主要监控该目录下文件的增加和删除事件。五个目录如下。
system/framework:存放系统框架层JAR包及其对应的ODEX文件,另外还有framework-res.apk资源包。
system/app:存放系统内置应用程序的APK文件及其对应的ODEX文件。
vendor/app:存放厂商定制的APK文件及其对应的ODEX文件。
data/app:存放其他APK文件及其对应的ODEX文件。
data/app-private:存放受保护的APK文件及其对应的ODEX文件。
代码如下:
//监控system/framework目录
mFrameworkInstallObserver=new AppDirObserver(
mFrameworkDir.getPath(),OBSERVER_EVENTS, true);
mFrameworkInstallObserver.startWatching();
//安装system/framework目录下的APK文件,默认只有framework-res.apk
scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
|PackageParser.PARSE_IS_SYSTEM_DIR,
scanMode|SCAN_NO_DEX,0);
//监控system/app目录
mSystemAppDir=……//实现代码同上
//监控vendor/app目录
mVendorAppDir=……
if(!mOnlyCore){
//监控data/app目录
mAppInstallObserver=……
//监控data/app-private目录
mDrmAppInstallObserver=……
……
mFrameworkInstallObserver、mSystemInstallObserver、mVendorInstallObserver是三个FileObserver类型的监听器。FileObserver基于Linux的Inotify机制,会监听到文件系统中文件或目录的添加和删除事件,并做出响应。监听事件由其startWatching方法负责,而响应事件的具体操作由FileObserver的子类AppDirObserver的onEvent方法实现。这里主要监听和响应添加包和删除包的事件,代码如下:
private final class AppDirObserver extends FileObserver{
……
public void onEvent(int event, String path){
……
if((event&REMOVE_EVENTS)!=0){//响应移除包事件
if(p!=null){
removePackageLI(p, true);//调用removePackageLI移除包
removedPackage=p.applicationInfo.packageName;
removedUid=p.applicationInfo.uid;
}
}
if((event&ADD_EVENTS)!=0){//响应添加包事件
if(p==null){//调用scanPackageLI执行APK扫描安装操作
p=scanPackageLI(fullPath,……);
if(p!=null){//更新permission信息
synchronized(mPackages){
updatePermissionsLPw(p.packageName,……);
}
addedPackage=p.applicationInfo.packageName;
addedUid=p.applicationInfo.uid;
}
}
}
synchronized(mPackages){
mSettings.writeLPr();//更新packages.xml文件
}
}
if(removedPackage!=null){//发送移除包的广播
……
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
removedPackage, extras, null, null);
}
if(addedPackage!=null){//发送添加包的广播
Bundle extras=new Bundle(1);
extras.putInt(Intent.EXTRA_UID, addedUid);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
addedPackage, extras, null, null);
}
}
在onEvent方法中,响应两种事件:REMOVE_EVENTS和ADD_EVENTS。如果通过adb push命令将某个APK包push到/data/app目录下,则mAppInstallObserver的onEvent方法就会被触发并执行APK的安装操作。安装后需要调用mSettings.writeLPr()方法更新packages.xml文件,并发送相应广播通知其他模块。