欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 插件化技术窥探

程序员文章站 2022-05-27 21:49:13
在Android 插件化技术中(宿主app和插件app设置相同的sharedUserId),动态加载apk有两种方式: 一种是将资源主题包的apk安装到手机上再读取apk内的资源,这种方式的原理是将宿主app和插件app设置相同的sharedUserId,这样两个app将会在同一个进程中运行,并可以 ......

在android 插件化技术中(宿主app和插件app设置相同的shareduserid),动态加载apk有两种方式:

  • 一种是将资源主题包的apk安装到手机上再读取apk内的资源,这种方式的原理是将宿主app和插件app设置相同的shareduserid,这样两个app将会在同一个进程中运行,并可以相互访问内部资源了。
  • 一种是不用安装资源apk的方式。其原理是通过dexclassloader类加载器去加载指定路径下的apk、dex或者jar文件,反射出r类中相应的内部类然后根据资源名来获取我们需要的资源id,然后根据资源id得到对应的图片或者xml文件。

下面介绍几种常见的方法获取资源以及代码的方法。

  • 获取已安装的apk中的资源
    利用context的createpackagecontext方法,可以创建另外一个包的上下文,里面有两个参数packagename包名,flags 标志位(context_include_code、context_ignore_security)
    用法如下
try {  
    context = createpackagecontext("com.test.resource", 
                                   context.context_include_code  
                                  | context.context_ignore_security);  
    textview.settext(context.getresources().gettext(r.string.message));  
} catch (namenotfoundexception e) {  
   e.printstacktrace();  
}  
  • 获取未安装的apk中的资源

新建一个获取资源的接口,传入插件apk的路径返回resources对象

// 获取插件apk的resources对象
public resources getbundleresource(context context, string apkpath) {
    assetmanager assetmanager = createassetmanager(apkpath);
    return new resources(assetmanager, 
                         context.getresources().getdisplaymetrics(), 
                         context.getresources().getconfiguration());
}

private assetmanager createassetmanager(string apkpath) {
    try {
        assetmanager assetmanager = assetmanager.class.newinstance();
        assetmanager.class.getdeclaredmethod("addassetpath", string.class)
                          .invoke(assetmanager, apkpath);
        return assetmanager;
    } catch (throwable th) {
        th.printstacktrace();
    }
    return null;
}

获得了resource 对象之后,就可以通过函数resources.getdrawable、resources.getstring、resources.getlayout 获取图片、字符串、布局文件了。