占位式插件化Service和activity如出一辙,也是将宿主app的环境注入给插件app,主要原理如下:

由于插件里没有宿主环境,因此插件里的acitvity若要启动service必须将跳转的路径先传给宿主activity,如下:
startService(activity,TestService.class);
@Override
public ComponentName startService(Intent service) {
Intent intent = new Intent();
intent.putExtra("className", service.getComponent().getClassName());
return activity.startService(intent);
}
宿主activity在收到插件的跳转service方法后,将intent传过来的文件路径获取经作为参数传给代理service,并启动代理service:
@Override
public ComponentName startService(Intent service) {
Intent intent = new Intent(this,ProxyService.class);
intent.putExtra("className",service.getStringExtra("className"));
return super.startService(intent);
}
代理service收到传过来的className后加载插件包里对应的service实例,注入环境并通过接口调用相应的service方法。
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String className = intent.getStringExtra("className");
try {
Class service = PluginManager.getInstance(this).getClassLoader().loadClass(className);
ServiceInterface mService = (ServiceInterface) service.newInstance();
mService.insertService(this);
mService.onStartCommand(intent,flags,startId);
} catch (Exception e) {
e.printStackTrace();
}
return super.onStartCommand(intent, flags, startId);
}
插件里的service则循环打印日志证明其被启动了。
public class TestService extends BaseService {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
Log.e("TAG","打印了。。。。");
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
}
intent的跳转可能有些混乱,其实就是一个循坏,插件跳转时调用宿主的跳转方法并将跳转路径传递给宿主activity,宿主启动自己的service并将跳转路径传递给自己(即代理service)。自己获取到路径后加载插件包里的service实例,注入环境并调用相应的service方法。完毕。
网友评论