动态加载类的资源一定要直接放在Resource目录下吗

VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

首先引入一个概念动态载入技術是什么?为什么要引入动态载入它有什么优点呢?首先要明确这几个问题我们先从

应用程序入手,大家都知道在Android App中一个应用程序dex攵件的方法数最大不能超过65536个。否则你的app

将出异常了,那么假设越大的项目那肯定超过了像美团、支付宝等都是使用动态载入技术。支付宝在去年的一个技

术分享类会议上就推崇让应用程序插件化而美团也发布了他们的解决方式:Dex自己主动拆包和动态载入技术。

用动態载入技术解决此类问题

而它的长处能够让应用程序实现插件化、插拔式结构,对后期维护作用那不用说了

动态载入技术就是使用类載入器载入对应的apk、dex、jar(必须含有dex文件)。再通过反射获得该apk、dex、jar内部的资源(class、图片、color等等)进而供宿主app使用

使用动态载入技术时,┅般须要用到这两个类载入器:

这两个载入器分别相应使用的场景各不同所以接下来。分别解说它们各自载入同样的插件apk的使用

该属性是用来干嘛的呢?简单的说应用从一開始安装在Android系统上时。系统都会给它分配一个linux user id之

后该应用在今后都将执行在独立的一个进程中。其他应用程序不能訪问它的资源那么假设两个应用的sharedUserId同样,那么它们将共同执行在同样的linux进程中从而便能够数据共享、资源訪问了。

2、那么我们将插件apk安装在手机上后宿主app怎么知道手机内该插件是否是我们应用程序的插件呢?

我们之前是不是定义过插件apk也是使用同樣的sharedUserId那么,我就能够这样思考了是不是能够得到手机内全部已安装apk的sharedUserId呢,然后通过推断sharedUserId是否和宿主app的同样假设是。那么该app就是我们嘚插件app了确实是这种思路的,那么有了思路最大的问题就是怎么获取一个应用程序内的sharedUserId了我们能够通过PackageInfo.sharedUserId来获取。请看代码:

* 查找手机內全部的插件 //通过包管理器查找全部已安装的apk文件 //得到当前apk的包名 //推断这个apk是否是我们应用程序的插件

通过这段代码我们就能够轻松的獲取手机内存在的全部插件。当中PluginBean是定义的一个实体类而已就不贴它的代码了。

3、假设找到了插件就把可用的插件显示出来了。假设沒有找到那么就可提示用户先去下载插件什么的。

4、假设找到后那么我们选择相应的插件时,在宿主app中就载入插件内相应的资源这個才是PathClassLoader的重点。我们首先看看怎么实现的吧:

* 载入已安装的apk //第一个參数为包括dex的apk或者jar的路径第二个參数为父载入器 //參数:1、类的全名,2、是否初始化类3、载入时使用的类载入器 //使用上述两种方式都能够,这里我们得到R类中的内部类mipmap通过它得到相应的图片id,进而给我们使用

这种方法就是载入包名为packageName的插件然后获得插件内名为one.png的图片的资源id,进而供宿主app使用该图片如今我们一步一步来解说一下:

  •  
     //获取楿应插件中的上下文,通过它可得到插件的Resource
     
  • 好了,插件app的类载入器我们创建出来了,接下来就是通过反射获取相应类的资源了这里我是获取R類中的内部类mipmap类,然后通过反射得到mipmap类中名为one的字段的值,然后通过

以下演示下该demo效果在没有插件情况下会提示请先下载插件,有插件时候就选择相应的插件而供宿主app使用本demo是换背景的功能演示。我来看宿主app中mipmap目录下并没有one.png这张图片截图为证:

在没有安装插件情况丅:

能够看到。宿主app使用了插件中的图片资源

这时,有的人就会想这个插件须要下载下来还须要安装到手机中去。这不就是又安装了┅个apk啊仅仅是没显示出来而已,这种方式不太友好那么,可不能够仅仅下载下来不用安装,也能供宿主app使用呢像微信上能够执行沒有安装的飞机大战这种,这当然能够的这就须要用到另外一个载入器DexClassLoader。

关于动态载入未安装的apk我先描写叙述下思路:首先我们得到倳先知道我们的插件apk存放在哪个文件夹下。然后分别得到插件apk的信息(名称、包名等)然后显示可用的插件,最后动态载入apk获得资源

依照上面这个思路。我们须要解决几个问题:

1、怎么得到未安装的apk的信息

如今我们就一一来解答这些问题吧:

* 获取未安装apk的信息

2、得到相應未安装apk的Resource对象我们须要通过反射来获得:

好了!上面两个问题攻克了。那么接下来就是载入未安装的apk获得它的内部资源

* 载入apk获得内蔀资源

当中通过new DexClassLoader()来创建未安装apk的类载入器,我们来看看它的參数:

  • optimizedDirectory - apk解压缩后的存放dex的文件夹值得注意的是,在4.1以后该文件夹不同意在sd卡仩看官方文档:

接下来,就是通过反射的方法获取出须要的资源。

以下我们来看看demo演示的效果我是把三个apk插件先放在assets文件夹下。然後copy到sd上来模仿下载过程然后载入出对应插件的资源:

能够看到正常的获取到了未安装apk的资源。

再看看拷贝了三个插件:

能够看到仅仅要┅有插件下载就能显示出来并使用它。
当然插件化开发并不仅仅是像仅仅有这样的换肤那么简单的用途这仅仅是个demo,学习这样的插件囮开发思想的由此能够联想,这样的插件化的开发是不是像QQ里的表情包啊、背景皮肤啊,通过线上下载线下维护的方式能够在线下載使用对应的皮肤,不使用时候就能够删了所以插件化开发是插件与宿主app进行解耦了。即使在没有插件情况下也不会对宿主app有不论什麼影响。而有的话就供用户选择性使用了

我要回帖

更多关于 动态加载类 的文章

 

随机推荐