Android APK应用安装原理(2)-查找APK并自动安装

来源:未知 责任编辑:智问网络 发表时间:2013-10-30 11:04 点击:

Android每次启动的时候会自动安装位于特定目录下的APK,这个过程会在packageManagerService这个类的构造方法中进行,这里会创建多个目录用于预查找:

[java] view plaincopy

  1. public PackageManagerService(Context context, boolean factoryTest) {  
  2.   
  3. ...  
  4.   
  5. mFrameworkDir = new File(Environment.getRootDirectory(), "framework"); // system/framework  
  6.   
  7. mSystemAppDir = new File(Environment.getRootDirectory(), "app"); // system/app  
  8.   
  9. mAppInstallDir = new File(dataDir, "app"); // data/app  
  10.   
  11. mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); // data/app-private  
  12.   
  13. mAppDataDir = new File(dataDir, "data"); // data/data  
  14.   
  15. ...  
  16.   
  17. }  



它会在这5个地方寻找APK并通过Installer这个类来安装,通过

[java] view plaincopy

  1. synchronized (mInstallLock) {  
  2.    synchronized (mPackages) {  
  3.      ......  
  4.    }  
  5. }  

可以看出,同时只能对一个应用进行安装或者删除,且对一个应用做一个操作的时候就不能对同一个应用做另外一个操作
同时可写的目录就会添加AppObserver 用于监听目录下的变化并调用removePackageLI或者scanPackageLI方法,前者用于删除应用,后者用于安装,这里说的安装仅仅只是将解析过的manifest以一些数据结构的形式保存在packageManagerService中,也就是保存在了内存中并常驻内存,以后系统或者非系统的应用发出的任何意图都会在这里查找匹配的组件。

而真正意义上的安装是安装器 Lnstaller这个类在处理的,你可以讲一个APK文件的后缀改为.RAR 然后解压,会看到里面有里面有一个AndroidManifest.xml,classes.dex,assets

,META-INF和res,而真正的安装是把这些除了manifest之外的东西放到android系统的相应的目录中去,其中classes.dex相当于dailvk虚拟机上的可执行文件,assets是放的一些不会被变异的原始资源,res里是一些DEX要用到的资源,META-INF是描述APK的元数据



而Installer完整安装的原理又是什么呢?  com.android.server.Installer这个类其实是通过 ADB命令来安装的,相当于 adb install xx.xx.xx  :

[java] view plaincopy

  1. public int install(String name, int uid, int gid) {  
  2.         StringBuilder builder = new StringBuilder("install");  
  3.         builder.append(' ');  
  4.         builder.append(name);  
  5.         builder.append(' ');  
  6.         builder.append(uid);  
  7.         builder.append(' ');  
  8.         builder.append(gid);  
  9.         return execute(builder.toString());  
  10.     }  


execute的实现又是

[java] view plaincopy

  1. private int execute(String cmd) {  
  2.         String res = transaction(cmd);  
  3.         try {  
  4.             return Integer.parseInt(res);  
  5.         } catch (NumberFormatException ex) {  
  6.             return -1;  
  7.         }  
  8.     }  


transaction又是通过writeCommand(cmd)这个方法实现的

[java] view plaincopy

  1. private boolean writeCommand(String _cmd) {  
  2.         byte[] cmd = _cmd.getBytes();  
  3.         int len = cmd.length;  
  4.         if ((len < 1) || (len > 1024)) return false;  
  5.         buf[0] = (byte) (len & 0xff);  
  6.         buf[1] = (byte) ((len >> 8) & 0xff);  
  7.         try {  
  8.             mOut.write(buf, 02);  
  9.             mOut.write(cmd, 0, len);  
  10.         } catch (IOException ex) {  
  11.             Slog.e(TAG,"write error");  
  12.             disconnect();  
  13.             return false;  
  14.         }  
  15.         return true;  
  16.     }  


这里的mOut 是通过LocalSocket这个类获得的runtime运行时环境的流,往流里写东西然后刷新进去 就相当于在窗口下输入 各种指令了,所以真正安装的更底层的步骤就只有看adb这个命令的C/C++的源码了~

好了基本的安装步骤和原理就是这样的啦~!
    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • Android 完全退出程序
    • 原创:Android应用开发-Andorid歌词秀,含源码
    • android 屏幕保护
    • Android手机软件汉化教程---第四课 dex文件汉化
    • 众多Android 开源项目推荐,给力工作给力学习
    • Android Audio代码分析4
    • Android得到已安装的应用程序信息!
    • Android开发者指南(29) —— USB Host and Accessory
    • Android成长的幕后推手:工程师鲁宾
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1