您的位置:首页 > 移动开发 > Android开发

Android应用程序安装过程源代码分析(3)

2011-09-14 01:01 489 查看
Step 7. PackageManagerService.main

这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:

[cpp] view plaincopy

class PackageManagerService extends IPackageManager.Stub {

......

public static final IPackageManager main(Context context, boolean factoryTest) {

PackageManagerService m = new PackageManagerService(context, factoryTest);

ServiceManager.addService("package", m);

return m;

}

......

}

这个函数创建了一个PackageManagerService服务实例,然后把这个服务添加到ServiceManager中去,ServiceManager是Android系统Binder进程间通信机制的守护进程,负责管理系统中的Binder对象,具体可以参考浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路一文。
在创建这个PackageManagerService服务实例时,会在PackageManagerService类的构造函数中开始执行安装应用程序的过程:

[java] view plaincopy

class PackageManagerService extends IPackageManager.Stub {

......

public PackageManagerService(Context context, boolean factoryTest) {

......

synchronized (mInstallLock) {

synchronized (mPackages) {

......

File dataDir = Environment.getDataDirectory();

mAppDataDir = new File(dataDir, "data");

mSecureAppDataDir = new File(dataDir, "secure/data");

mDrmAppPrivateInstallDir = new File(dataDir, "app-private");

......

mFrameworkDir = new File(Environment.getRootDirectory(), "framework");

mDalvikCacheDir = new File(dataDir, "dalvik-cache");

......

// Find base frameworks (resource packages without code).

mFrameworkInstallObserver = new AppDirObserver(

mFrameworkDir.getPath(), OBSERVER_EVENTS, true);

mFrameworkInstallObserver.startWatching();

scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM

| PackageParser.PARSE_IS_SYSTEM_DIR,

scanMode | SCAN_NO_DEX, 0);

// Collect all system packages.

mSystemAppDir = new File(Environment.getRootDirectory(), "app");

mSystemInstallObserver = new AppDirObserver(

mSystemAppDir.getPath(), OBSERVER_EVENTS, true);

mSystemInstallObserver.startWatching();

scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM

| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

// Collect all vendor packages.

mVendorAppDir = new File("/vendor/app");

mVendorInstallObserver = new AppDirObserver(

mVendorAppDir.getPath(), OBSERVER_EVENTS, true);

mVendorInstallObserver.startWatching();

scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM

| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

mAppInstallObserver = new AppDirObserver(

mAppInstallDir.getPath(), OBSERVER_EVENTS, false);

mAppInstallObserver.startWatching();

scanDirLI(mAppInstallDir, 0, scanMode, 0);

mDrmAppInstallObserver = new AppDirObserver(

mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);

mDrmAppInstallObserver.startWatching();

scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,

scanMode, 0);

......

}

}

}

......

}

这里会调用scanDirLI函数来扫描移动设备上的下面这五个目录中的Apk文件

/system/framework
/system/app
/vendor/app
/data/app
/data/app-private
Step 8. PackageManagerService.scanDirLI

这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:

[java] view plaincopy

class PackageManagerService extends IPackageManager.Stub {

......

private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {

String[] files = dir.list();

......

int i;

for (i=0; i<files.length; i++) {

File file = new File(dir, files[i]);

if (!isPackageFilename(files[i])) {

// Ignore entries which are not apk's

continue;

}

PackageParser.Package pkg = scanPackageLI(file,

flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);

// Don't mess around with apps in system partition.

if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&

mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {

// Delete the apk

Slog.w(TAG, "Cleaning up failed install of " + file);

file.delete();

}

}

}

......

}

对于目录中的每一个文件,如果是以后Apk作为后缀名,那么就调用scanPackageLI函数来对它进行解析和安装。

Step 9. PackageManagerService.scanPackageLI

这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:

[java] view plaincopy

class PackageManagerService extends IPackageManager.Stub {

......

private PackageParser.Package scanPackageLI(File scanFile,

int parseFlags, int scanMode, long currentTime) {

......

String scanPath = scanFile.getPath();

parseFlags |= mDefParseFlags;

PackageParser pp = new PackageParser(scanPath);

......

final PackageParser.Package pkg = pp.parsePackage(scanFile,

scanPath, mMetrics, parseFlags);

......

return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);

}

......

}

这个函数首先会为这个Apk文件创建一个PackageParser实例,接着调用这个实例的parsePackage函数来对这个Apk文件进行解析。这个函数最后还会调用另外一个版本的scanPackageLI函数把来解析后得到的应用程序信息保存在PackageManagerService中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息