Android动态加载技术(插件化技术)
No1:
插件化技术的好处:
1)减轻应用的内存和CPU占用
2)实现热插拔,即在不发布新版本的情况下更新某些模块
No2:
插件化方案必须要解决三个基础性问题:资源访问、Activity生命周期的管理和ClassLoader的管理
No3:
宿主是指普通的apk,插件一般指经过处理的dex或者apk。插件化框架大多采用apk作为插件,很多需要用到代理Activity,插件Activity的启动大多数是借助一个代理Activity来实现的。
No4:
Activity的工作主要是通过ContextImpl来完成的,Activity中有一个交mBase的成员变量,它的类型就是ContextImpl。Context中有两个抽象方法getAssets和getResources,通过它们来获取资源的,真正实现在ContextImpl中。
No5:
资源访问
加载apk中的资源
protected void loadResources(){
try{
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath",String.class);
addAssetPath.invoke(assetManager,mDexPath);
mAssetManager = assetManager;
}catch(Exception e){
e.printStackTrace();
}
Resources superRes = super.getResources();
mResources = new Resources(mAssetManager,superRes.getDisplayMetrics(),superRes.getConfiguration());
mTheme = mResources.newTheme();
mTheme.setTo(super.getTheme());
}
通过反射,调用AssetManager中addAssetPath方法,将一个apk中的资源加载到Resources对象中。然后通过AssetManager来创建一个新的Resources对象
public final int addAssetPath(String path){
synchronized(this){
int res = addAssetPathNative(path);
makeStringBlocks(mStringBlocks);
return res;
}
}
接着在代理Activity中实现getAssets和getResources
@Override
public AssetManager getAssets(){
return mAssetManager == null?super.getAssets():mAssetManager;
} @Override
public Resources getResources(){
return mResources == null?super.getResources():mResources;
}
No6:
Activity生命周期的管理
反射方式
@Override
protected void onResume(){
super.onResume();
Method onResume = mActivityLifecircleMethods.get("onResume");
if(onResume!=null){
try{
onResume.invoke(mRemoteActivity,new Object[]{ })
}catch(Exception e){
e.printStackTrace();
}
}
} @Override
protected void onPause(){
Method onPause = mActivityLifecircleMethods.get("onPause");
if(onPause!=null){
try{
onPause.invoke(mRemoteActivity,new Object[]{ })
}catch(Exception e){
e.printStackTrace();
}
}
super.onPause();
}
接口方式
public interface DLPlugin{
public void onStart();
public void onRestart();
public void onResume();
public void onPause();
public void onStop();
public void onDestroy();
...
}
代理Actvitiy中调用
...
@Override
protected void onStart(){
mRemoteActivity.onStart();
super.onStart();
} @Override
protected void onRestart(){
mRemoteActivity.onRestart();
super.onRestart();
} @Override
protected void onResume(){
mRemoteActivity.onResume();
super.onResume();
}
mRemoteActivity就是DLPlugin的实现
No7:
插件ClassLoader的管理
public class DLClassLoader extends DexClassLoader{
private static final String TAG ="DLClassLoader";
private static final HashMap<String,DLClassLoader> mPluginClassLoaders = new HashMap<String,DLClassLoader>();
protected DLClassLoader(String dexPath,String optimizedDirectory,String libraryPath,Classloader parent){
super(dexPath,optimizedDirectory,libraryPath,parent);
}
public static DLClassLoader getClassLoader(String dexPath,Context context,Classloader parentLoader){
DLClassLoader dLassLoader = mPluginClassLoaders.get(dexPath);
if(dLassLoader != null){
return DLClassLoader;
}
File dexOutputDir = context.getDir("dex",Context.MODE_PRIVATE);
final String dexOutputPath = dexOutputDir.getAbsolutePath();
dLClassLoader = new DLClassLoader(dexPath,dexOutputPath,null,parentLoader);
mPluginClassLoaders.put(dexPath,dLClassLoader);
return dLClassLoader;
}
}
通过将不同插件的ClassLoader存储在一个HashMap中,这样就可以保证不同插件中的类彼此互不干扰。
Android动态加载技术(插件化技术)的更多相关文章
- Adroid动态加载Apk-插件化技术框架(动态代理方案)
技术:Android + java +动态加载+插件化 概述 为什么要使用插件化?在开发中,一个项目只会越做越大.初始版本可能是单一功能,后续可能加上各种风马牛不相及的功能.所以我认为插件化可以使 ...
- Android动态加载代码技术
Android动态加载代码技术 在开发Android App的过程当中,可能希望实现插件式软件架构,将一部分代码以另外一个APK的形式单独发布,而在主程序中加载并执行这个APK中的代码. 实现这个任务 ...
- Android动态加载技术初探
一.前言: 现在,已经有实力强大的公司用这个技术开发应用了,比如淘宝,大众点评,百度地图等,之所以采用这个技术,实际上,就是方便更新功能,当然,前提是新旧功能的接口一致,不然会报Not Found等错 ...
- 深入浅出Android动态加载jar包技术
在实际项目中,由于某些业务频繁变更而导致频繁升级客户端的弊病会造成较差的用户体验,而这也恰是Web App的优势,于是便衍生了一种思路,将核心的易于变更的业务封装在jar包里然后通过网络下载下来,再由 ...
- Android 动态加载 (一) 态加载机制 案例一
在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...
- Android 动态加载(防止逆向编译) jar混淆加密
最近工作中接到了一个研究防止逆向编译的任务.研究了几天资料,最后基本实现了防破解技术,在这个工程中,也略有一些心得体会,现整理下来分享,供大家探讨参考研究.文中如有纰漏.失实之处,请大家及时给与指正. ...
- 【Android】Android动态加载Jar、APK的实现
本文介绍Android中动态加载Jar.APK的实现.而主要用到的就是DexClassLoader这个类.大家都知道Android和普通的Java虚拟机有差别,它只能加载经过处理的dex文件.而加载这 ...
- android动态加载
转载自: http://www.cnblogs.com/over140/archive/2012/03/29/2423116.html http://www.cnblogs.com/over140/a ...
- Android动态加载jar/dex
前言 在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优 ...
- [转载] Android动态加载Dex机制解析
本文转载自: http://blog.csdn.net/wy353208214/article/details/50859422 1.什么是类加载器? 类加载器(class loader)是 Java ...
随机推荐
- scrapy_开发环境
scrapy开发所具备的环境 IDE pycharm 数据库 mysql, redis 开发环境 python 3.5
- JAVA中限制接口流量、并发的方法
JAVA中限制接口流量可以通过Guava的RateLimiter类或者JDK自带的Semaphore类来实现,两者有点类似,但是也有区别,要根据实际情况使用.简单来说, RateLimiter类是控制 ...
- ecplise最有用的8个快捷键
1. ctrl+shift+r 打开资源 这组快捷键可以让你打开你工作区中的任何一个文件.而你只需要按下键盘的文件名或前几个字母 美中不足的是这组快捷键并非在所有视图下都能用. 2.ctrl+o:快速 ...
- Halcon一日一练:Halcon异常判断方法
1.TryCatch tryCatch处理的方式如下: try *可能会出现错误的语句 .... catch(Exception) *获取错误代码 ErrorCode:=Exception[] **对 ...
- 事件委托live,delegate,on区别
事件委托 我们知道,DOM在为页面中的每个元素分派事件时,相应的元素一般都在事件冒泡阶段处理事件.在类似 body > div > a 这样的结构中,如果单击a元素,click事件会从a一 ...
- JAVA 调用 R 语言之升华篇
由于项目的需要,最近做了一个javaWeb调用R的组件,在这里,我把自己走的一些弯路给大家总结一下: 一.选取什么插件作为java和R之间的通信? 1. 在传统的方式中,大致可以分为两类:一类是JRI ...
- 看图说话,P2P 分享率 90% 以上的 P2P-CDN 服务,来了!
事情是这样的:今年年初的时候,公司准备筹划一个直播项目,在原有的 APP 中嵌入直播模块,其中的一个问题就是直播加速服务的选取. 老板让我负责直播加速的产品选型,那天老板把我叫到办公室,语重心长地说: ...
- SpringMVC源码情操陶冶-ResourcesBeanDefinitionParser静态资源解析器
解析mvc:resources节点,控制对静态资源的映射访问 查看官方注释 /** * {@link org.springframework.beans.factory.xml.BeanDefinit ...
- web开发过程中关于路径问题的总结
约束: 相对路径概念-./代表当前目录.../代表上级目录 示例的所有文件都基于http://127.0.0.1:8080/test路径开放,test为对应的contextPath 前端 HTML标签 ...
- BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]
传送门 题面太美不忍不放 分块分块 这种题的一个特点是只有查询,通常需要预处理:加入修改的话需要暴力重构预处理 预处理$f[i][j]$为第i块到第j块的众数,显然$f[i][j]=max{f[i][ ...