免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 961 | 回复: 0
打印 上一主题 下一主题

包管理系统分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-06 11:32 |只看该作者 |倒序浏览
包管理脚本 /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=/system
export CLASSPATH=$base/framework/pm.jar
exec 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 PACKAGE
pm install [-l] [-r] PATH
安装软件包 PATH 为apk文件的路径 , -l 表示采用 FORWARD_LOCK 的方式安装,-r 如果一个包存在那么
重新安装,但是保留原来的数据。
pm uninstall [-k] PACKAGE
卸载一个软件包,PACKAGE 为软件包的名称,-k选项表明卸载的时候保留数据和相应的cache目录。
pm enable PACKAGE_OR_COMPONENT
pm disable PACKAGE_OR_COMPONENT
enable 和 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()
执行 run
run 调用  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 receivers
  final PackageManager pm = context.getPackageManager();
  List 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)
补充信息:
getLaunchIntentForPackage
getInstalledPackages
getInstalledApplications
getDefaultActivityIcon
getApplicationLabel
addPackageToPreferred

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/49742/showart_1919523.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP