android 包管理系统分析

    技术2025-01-09  47

    包管理脚本 /system/bin/pm 解析:

    pm的使用方法可以参考 Pm.java (frameworks/base/cmds/pm/src/com/android/commands/pm)文件中的static void showUsage()函数:private static void showUsage() {        System.err.println("usage: pm [list|path|install|uninstall]");        System.err.println("       pm list packages [-f]");        System.err.println("       pm list permission-groups");        System.err.println("       pm list permissions [-g] [-f] [-d] [-u] [GROUP]");        System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");               System.err.println("       pm path PACKAGE");        System.err.println("       pm install [-l] [-r] PATH");        System.err.println("       pm uninstall [-k] PACKAGE");        System.err.println("       pm enable PACKAGE_OR_COMPONENT");        System.err.println("       pm disable PACKAGE_OR_COMPONENT");   ...}脚本 /system/bin/pm 内容:----------------------------------------------------------base=/systemexport CLASSPATH=$base/framework/pm.jarexec app_process $base/bin com.android.commands.pm.Pm "$@"----------------------------------------------------------pm脚步执行过程分析:由命令行参数可以知道调用过程如下:首先进入 App_main.cpp (frameworks/base/cmds/app_process)文件中AppRuntime 类的 main 函数。main()set_process_name(argv0);runtime.mClassName = arg;runtime.mArgC = argc-i;runtime.mArgV = argv+i;runtime.start();runtime.start 调用的是 AndroidRuntime.cpp (frameworks/base/core/jni)文件中的:void AndroidRuntime::start()    start("com.android.internal.os.RuntimeInit",false /* Don't start the system server */);然后进入 RuntimeInit 类的main函数RuntimeInit.java (frameworks/base/core/java/com/android/internal/os)main()commonInit();finishInit();finishInit 实际上本地调用:AndroidRuntime.cpp (frameworks/base/core/jni)中的:static void com_android_internal_os_RuntimeInit_finishInit(JNIEnv* env, jobject clazz)    gCurRuntime->onStarted();因为有:App_main.cpp (frameworks/base/cmds/app_process):    virtual void onStarted()Main_runtime.cpp (frameworks/base/cmds/runtime):    virtual void onStarted()而 class AppRuntime : public AndroidRuntime 并且是由 AppRuntime 类进入 RuntimeInit所以可以确定 gCurRuntime->onStarted() 调用的是App_main.cpp (frameworks/base/cmds/app_process)中的:virtual void onStarted() 函数。app_init(mClassName, mArgC, mArgV);接着,status_t app_init(const char* className, int argc, const char* const argv[])    jr->callMain(className, argc, argv);jr->callMain 调用了 Pm.java (frameworks/base/cmds/pm/src/com/android/commands/pm) 文件中类 Pm 的main函数static void main(String[] args)new Pm().run(args)在run函数中对参数进行解析。此处的args 实际上为执行pm脚本时 传入的参数。pm 脚本常见的格式有:---------------------------------------------------pm list packages [-f]显示系统中所有已安装的软件包,-f选项列出他们的相关信息pm list permission-groups");pm list permissions [-g] [-f] [-d] [-u] [GROUP]pm list instrumentation [-f] [TARGET-PACKAGE]     pm path PACKAGEpm install [-l] [-r] PATH安装软件包 PATH 为apk文件的路径 , -l 表示采用 FORWARD_LOCK 的方式安装,-r 如果一个包存在那么重新安装,但是保留原来的数据。pm uninstall [-k] PACKAGE卸载一个软件包,PACKAGE 为软件包的名称,-k选项表明卸载的时候保留数据和相应的cache目录。pm enable PACKAGE_OR_COMPONENTpm disable PACKAGE_OR_COMPONENTenable 和 disable 修改一个包或者组件(class)的使能状态.----------------------------------------------------例如:我们输入命令 pm install /patch/to/mygps.apk那么执行的是:runInstall();void runInstall()while ((opt=nextOption()) != null) {if (opt.equals("-l")) {    installFlags |= PackageManager.FORWARD_LOCK_PACKAGE;} else if (opt.equals("-r")) {    installFlags |= PackageManager.REPLACE_EXISTING_PACKAGE;}String apkFilePath = nextArg();//创建Observer用于包安装过程的监测。PackageInstallObserver obs = new PackageInstallObserver();mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags);如果安装成功:obs.result == PackageManager.INSTALL_SUCCEEDED因为有:IPackageManager mPm;mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));class PackageManagerService extends IPackageManager.Stub所以 mPm.installPackage 调用的是:PackageManagerService.java (frameworks/base/services/java/com/android/server)文件中的/* Called when a downloaded package installation has been confirmed by the user */void installPackage(final Uri packageURI, final IPackageInstallObserver observer, final int flags)res = installPackageLI(packageURI, flags);...Bundle extras = new Bundle(1);extras.putInt(Intent.EXTRA_UID, res.uid);...sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,res.pkg.applicationInfo.packageName,extras);如果包安装成功了,那么将广播一个 ACTION_PACKAGE_ADDED 的消息。下面的服务和应用程序会监测 ACTION_PACKAGE_ADDED 消息。AppWidgetService.java (frameworks/base/services/java/com/android/server): filter.addAction(Intent.ACTION_PACKAGE_ADDED);Home.java (development/samples/home/src/com/example/android/home):        filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);InputMethodManagerService.java (frameworks/base/services/java/com/android/server): packageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);Launcher.java (packages/apps/launcher/src/com/android/launcher):   IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);ManageApplications.java (packages/apps/settings/src/com/android/settings): IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);PackageBrowser.java (development/apps/development/src/com/android/development):IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);SearchDialog.java (frameworks/base/core/java/android/app): mPackageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);SearchManagerService.java (frameworks/base/core/java/android/server/search): filter.addAction(Intent.ACTION_PACKAGE_ADDED);下面将分析 SearchManagerService 服务对 ACTION_PACKAGE_ADDED 消息的监测过程:由pm的脚本分析,我们可以知道,安装一个包后会广播 ACTION_PACKAGE_ADDED 消息。而在 SearchManagerService 的构造函数SearchManagerService(Context context)中通过:        // Setup the infrastructure for updating and maintaining the list        // of searchable activities.        IntentFilter filter = new IntentFilter();        filter.addAction(Intent.ACTION_PACKAGE_ADDED);        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);        filter.addDataScheme("package");        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);添加了对 ACTION_PACKAGE_ADDED 消息的监测。当收到 ACTION_PACKAGE_ADDED 消息后,会执行 void onReceive(Context context, Intent intent)mHandler.post(mRunUpdateSearchable);接着,private Runnable mRunUpdateSearchable = new Runnable()执行 runrun 调用 updateSearchables();SearchManagerService.java (frameworks/base/core/java/android/server/search)private void updateSearchables()SearchableInfo.buildSearchableList(mContext);ComponentName defaultSearch = new ComponentName(                 "com.android.googlesearch",                 "com.android.googlesearch.GoogleSearch" );SearchableInfo.setDefaultSearchable(mContext, defaultSearch);由:ComponentName.java (frameworks/base/core/java/android/content)public ComponentName(String pkg, String cls)public ComponentName(Context pkg, String cls)public ComponentName(Context pkg, Class<?> cls)new ComponentName 调用的是 public ComponentName(String pkg, String cls)void buildSearchableList(Context context)//use intent resolver to generate list of ACTION_SEARCH receiversfinal PackageManager pm = context.getPackageManager();List<ResolveInfo> infoList;final Intent intent = new Intent(Intent.ACTION_SEARCH);infoList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);static void setDefaultSearchable(Context context,ComponentName activity)si = getSearchableInfo(context, activity);if (si != null) {    // move to front of list    sSearchablesList.remove(si);    sSearchablesList.add(0, si);}接着,static SearchableInfo getSearchableInfo(Context context, ComponentName activity)补充信息:getLaunchIntentForPackagegetInstalledPackagesgetInstalledApplicationsgetDefaultActivityIcongetApplicationLabeladdPackageToPreferred

    转自http://blog.csdn.net/linweig/archive/2010/04/09/5466393.aspx,非常感谢!

     

    最新回复(0)