Android动态加载技术(插件化技术)

2021年11月20日 阅读数:2
这篇文章主要向大家介绍Android动态加载技术(插件化技术),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。


No1:框架

插件化技术的好处:ide

1)减轻应用的内存和CPU占用this

2)实现热插拔,即在不发布新版本的状况下更新某些模块spa

No2:插件

插件化方案必需要解决三个基础性问题:资源访问、Activity生命周期的管理和ClassLoader的管理代理

No3:code

宿主是指普通的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中,这样就能够保证不一样插件中的类彼此互不干扰。