前言:
一直以来就对插件化这技术推崇已久,在去年也写过两篇关于插件化基础的文章:
都是关于classLoader如何加载外部apk中的代码,在"android中的动态加载"这篇博客末尾,提了下如何打开插件的activity,所以这篇文章就是谈如何通过代理Activity实现打开插件中的activity的。由于插件化的技术现在相对而言已经很成熟了,很多公司都已经运用在项目中,网上也有许多关于插件化的介绍,只是看到网上很多资料都写的不是很完整(可能我技术层面还没到达),只说了一些片面的代码或者是一些基础原理,并没有真正意义上的demo实现。原理是这么回事,但是真正到自己实现起来就发现知道原理并不能立马做好项目。网上也有许多demo是错误的,对初学者学习插件化造成了很大的困扰,在参考了许多资料之后,才决定写一篇关于如何实现插件化的文章。(这里对于宿主如何访问插件的资源、dexclassloader等就不再叙述了,这些基础知识网上有很多资料都有介绍)
参考资料:https://github.com/singwhatiwanna/dynamic-load-apk
实现代理activity的两种方式:(如何管理插件activity的生命周期)
1.通过反射方式实现代理activity。
2.通过接口方式实现代理activity
接下来就会分别使用以上两种方式实现插件化,先来看下运行结果。
了解过apk的安装都知道或者说了解PackageManagerService的都应该清楚,(如果不知道的可以看下我这篇博客:android apk安装过程源码解析)在安装过程中apk会被解析,然后apk中的信息比如四大组件都会被封装到一个package对象中,这样我们启动一个activity就只要从这个package对象中获取这个activity的信息就可以启动了。但是要启动一个插件中的activity(这个apk在外部,并没有被注册到我们的package中),这样的方式就行不通了。所以就需要在宿主activity中创建一个代理activity来管理插件activity的生命周期,而我们插件中的activity就相当于一个普通的类了。
先看下插件项目的目录结构:
可以看到我们的插件项目仅仅2个Activity以及一个接口,(这个接口是用来)其实从运行结果也能看到,插件就一个需要显示的activity,并且内容也仅仅是一个textview。接下来就来看下我们插件中的3个类的内容。
PluginInterface:
声明activity的生命周期方法,通过接口的方式来管理activity的生命周期,避免反射减少性能消耗。
package com.example.lujianxin.proxy;
import android.app.Activity;
import android.os.Bundle;
/**
* Created by lujianxin on 2017/7/14.
*/
public interface PluginInterface {
public void onStart();
public void onResume();
public void onPause();
public void onStop();
public void onDestroy();
public void onCreate(Bundle savedInstanceState);
public void setProxy(Activity proxyActivity);
}
这里仅仅只为demo服务,所以没有写另外的方法了,如果有需要可以根据自己的项目来添加.
BaseActivity:
package com.example.lujianxin.proxy;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
/**
* Created by lujianxin on 2017/7/13.
*/
public class BaseActivity extends Activity implements PluginInterface {
public