1. 动态加载技术概述
- 动态加载技术又称插件化技术
- 插件化可以减轻应用的内存和 CPU 占用以及 apk 包体积大小,还可以实现热插拔,即不发布新版本的情况下更新某些模块
- 插件化技术必须要解决的三个基础性问题
- 资源访问
- Activity 生命周期管理
- ClassLoader 的管理
2. 宿主和插件的概念
- 宿主是指普通的 apk,插件一般是指经过处理的 dex 或者 apk
- 主流的插件化框架中多采用经过特殊处理的 apk 来作为插件,处理方式往往和编译以及打包环节有关
- 很多插件化框架都需要用到代理 Activity 的概念,插件 Activity 的启动大多数是借助一个代理 Activity 来实现的
3. 插件化技术之资源访问
加载 apk 中的资源
1
2
3
4
5
6
7
8
9
10
11
12
13
14protected void loadResources() {
try {
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManger, mDexPath);
mAssetManger = assetManager;
} catch (Exception e) {
e.printStackTrace();
}
Resource superRes = super.getResources();
mResources = new Resources(mAssetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
mTheme = mResources.newTheme();
mTheme.setTo(super.getTheme());
}在代理 Activity 中实现
getAssets()
和getResources()
1
2
3
4
5
6
7
8
9
public AssetManager getAssets() {
return mAssetManager == null ? super.getAssets() : mAssetManager;
}
public Resoure getResources() {
return mResources == null ? super.getResources() : mResources;
}
4. 插件化技术之 Activity 生命周期的管理
反射方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
protected void onResume() {
super.onResume();
Method onResume = mActivityLifecircleMethods.get("onResume");
if (onResume != null) {
try {
onResume.invoke(mRemoteActivity, new Object[] {});
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void onPause() {
Method onPause = mActivityLifecircleMethods.get("onPause");
if (onPause != null) {
try {
onPause.invoke(mRemoteActivity, new Object[] {});
} catch (Exception e) {
e.printStackTace();
}
}
super.onPause();
}- 使用反射来管理插件 Activity 的生命周期有两个缺点:一是反射代码写起来比较复杂;二是过多使用反射会有一定的性能开销
接口方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 声明 DLPlugin
public interface DLPlugin {
public void onStart();
public void onRestart();
public void onActivityResult(int requestCode, int resultCode, Intent data);
public void onResume();
public void onPause();
public void onStop();
public void onDestroy();
public void onCreate(Bundle savedInstanceState);
public void setProxy(Activity proxyActivity, String dexPath);
public void onSaveInstanceState(Bundle outState);
public void onNewIntent(Intent intent);
public void onRestoreInstanceState(Bundle savedInstanceState);
public boolean onTouchEvent(MotionEvent event);
public boolean onKeyUp(int keyCode, KeyEvent event);
public void onWindowAttributesChanged(LayoutParams params);
public void onWindowFocusChanged(boolean hasFocus);
public void onBackPressed();
...
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 代理 Activity
...
protected void onStart() {
mRemoteActivity.onStart();
super.onStart();
}
protected void onRestart() {
mRemoteActivity.onRestart();
super.onRestart();
}
protected void onResume() {
mRemoteActivity.onResume();
super.onResume();
}
5. 插件化技术之插件 ClassLoader 的管理
1 | // 为了更好地对多插件进行支持,需要合理地去管理各个插件的 DexClassLoader |