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

本文详细阐述了Android系统中应用安装的过程,从特定目录搜索APK文件开始,通过PackageManagerService类进行查找,最终由Installer类完成完整安装。安装流程涉及目录管理、权限设置及资源放置等关键步骤。

        

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

public PackageManagerService(Context context, boolean factoryTest) {

...

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

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

mAppInstallDir = new File(dataDir, "app"); // data/app

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

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

...

}


它会在这5个地方寻找APK并通过Installer这个类来安装,通过
synchronized (mInstallLock) {
   synchronized (mPackages) {
     ......
   }
}
可以看出,同时只能对一个应用进行安装或者删除,且对一个应用做一个操作的时候就不能对同一个应用做另外一个操作
同时可写的目录就会添加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  :

public int install(String name, int uid, int gid) {
        StringBuilder builder = new StringBuilder("install");
        builder.append(' ');
        builder.append(name);
        builder.append(' ');
        builder.append(uid);
        builder.append(' ');
        builder.append(gid);
        return execute(builder.toString());
    }

execute的实现又是
private int execute(String cmd) {
		String res = transaction(cmd);
		try {
			return Integer.parseInt(res);
		} catch (NumberFormatException ex) {
			return -1;
		}
	}

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

private boolean writeCommand(String _cmd) {
		byte[] cmd = _cmd.getBytes();
		int len = cmd.length;
		if ((len < 1) || (len > 1024)) return false;
		buf[0] = (byte) (len & 0xff);
		buf[1] = (byte) ((len >> 8) & 0xff);
		try {
			mOut.write(buf, 0, 2);
			mOut.write(cmd, 0, len);
		} catch (IOException ex) {
            Slog.e(TAG,"write error");
			disconnect();
			return false;
		}
		return true;
	}

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

好了基本的安装步骤和原理就是这样的啦~!

typedef enum _HD_RESULT { HD_OK = 0, ///< general error HD_ERR_NOT_SUPPORT = -1, ///< not support ///< execute error HD_ERR_NG = -10, ///< general failure HD_ERR_SYS = -11, ///< operating system call failure HD_ERR_DRV = -12, ///< driver call failure HD_ERR_NOT_ALLOW = -13, ///< not allow in this case HD_ERR_ABORT = -14, ///< ignored or skipped HD_ERR_TIMEDOUT = -15, ///< timeout occured HD_ERR_FAIL = -19, ///< already executed and failed ///< module state error HD_ERR_INIT = -20, ///< module is already initialised HD_ERR_UNINIT = -21, ///< module is not initialised yet HD_ERR_STATE = -22, ///< invalid state to invoke function HD_ERR_TERM = -23, ///< module has terminated HD_ERR_NOT_OPEN = -24, ///< path is not open yet HD_ERR_ALREADY_OPEN = -25, ///< path is already open HD_ERR_NOT_START = -26, ///< path is not start yet HD_ERR_ALREADY_START = -27, ///< path is already start HD_ERR_NOT_BIND = -28, ///< io is not bind yet HD_ERR_ALREADY_BIND = -29, ///< io is already bind ///< parameter error HD_ERR_UNIQUE = -30, ///< unique id needed HD_ERR_DEV = -31, ///< invalid device id HD_ERR_IO = -32, ///< invalid io id HD_ERR_PATH = -33, ///< invalid path id HD_ERR_PARAM = -34, ///< invalid param id HD_ERR_INV = -35, ///< invalid argument passed HD_ERR_LIMIT = -36, ///< parameter value limit was reached HD_ERR_NULL_PTR = -37, ///< null pointer HD_ERR_NO_CONFIG = -38, ///< module device config or path config is not set HD_ERR_NO_DRV_CONFIG = -39, ///< module driver config is not set ///< object or resource error HD_ERR_RESOURCE = -40, ///< insufficient resources for request HD_ERR_NOT_AVAIL = -41, ///< resources not available HD_ERR_NOT_FOUND = -42, ///< not found HD_ERR_EOL = -43, ///< a list traversal has ended HD_ERR_IN_USE = -44, ///< object is in use. HD_ERR_NOT_USE = -45, ///< object is not in use. HD_ERR_LOCKED = -46, ///< object locked HD_ERR_DELETED = -47, ///< object has been deleted ///< data or buffer error HD_ERR_HEAP = -50, ///< heap full (application) HD_ERR_NOMEM = -51, ///< no memory (not enough system mem for create pool) HD_ERR_NOBUF = -52, ///< no buffer (not enough pool size for new blk) HD_ERR_SIGN = -53, ///< invalid sign in data HD_ERR_BAD_DATA = -54, ///< bad content in data HD_ERR_OVERRUN = -55, ///< buffer overrun occured, or data queue full HD_ERR_UNDERRUN = -56, ///< buffer underrun occured, or data queue empty ///< other error HD_ERR_INLINE_SUCCESS = -90, HD_ERR_INTERMEDIATE = -91, ///< intermediate return - successful but not complete HD_ERR_DEFERRED_SUCCESS = -92, HD_ERR_DEFERRED = -93, ///< action has been deferred HD_ERR_INV_PTR = -94, ///< invalid pointer HD_ERR_USER = -99, ///< start of subsystem specific errors } HD_RESULT; ///< HDAL error code
09-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值