赞
踩
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
在ActivityThread中对四大组件的生命周期方法调用,均是通过其内部类mH这个Handler进行分发的。而Service的生命周期源头onCreate方法则是命中了mH的CREATE_SERVICE(114)这个分支,最终调用到方法handleCreateService中。对应源码如下:
private void handleCreateService(CreateServiceData data) {
…
//看到这里是不是很熟悉,没错这个方法的最终实现也是调用到了方法getPackageInfo中
//在Activity篇中为了加载插件中的Activity,我们可是通过反射的方式调用到了getPackageInfo方法中以生成对应LoadedApk的缓存
//这里其实也是一样
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//看到这里是不是更加熟悉了,没错加载Activity类的ClassLoader也是从这个LoadedApk中获取的
//这里当然也是一样的,所以在后续Service插件化的实现中我们可以直接复用实现Activity插件中的相关代码
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//这里的最终实现就是痛过对应的ClassLoader加载名字为data.info.name对应的Service了
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//初始化Service,并调用其onCreate方法
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
service.onCreate();
//保存当前创建的Service对应,用于后续执行onStart、onBind、unBind以及onDestroy等方法
mServices.put(data.token, service);
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
Service的其它相关生命期方法与ActivityThread.java源码中方法实现分别对应关系如下:
onStartCommand:handleServiceArgs
onBind:handleBindService
onUnbind:handleUnbindService
onDestroy:handleStopService
看完源码实现之后你会发现,上述的几个生命周期方法所操作的Service实例对象都是在方法handleCreateService中所创建的对象。因此对于Service的插件化实现我们只需要拦截方法handleCreateService就足以。
有了上述源码的理解分析以及上一篇所实现Activity插件化的加持,对于Service插件化的实现那简直不要太简单。大致可以分为如下几个步骤:
第一步复用Activity插件化中所实现的AMNHook以及ActivityThread中Handler的hook
第二步就是在hook的AMN中对操作Service的相关方法startService、startService以及bindService三个方法进行拦截,并将要启动的Service替换成在宿主中所预埋的Service;
第三步就是在所hook的Handler中对方法handleCreateService进行拦截了。
因为AMN以及对应Handler的hook在Activity篇中有做注解,所以这里就不做过多的赘述了, 我们直接跳到第二步的代码实现。
/**
*
看着是不是so easy,简单来说就是吧上层应用需要启动的插件Service替换成宿主中预埋的Service以欺骗AMS;
最后就是在所hook的Handler中拦截方法handleCreateService了,对应的实现如下:
public void handleCreateService(Object object) {
try {
//首先获取从AMS传递过来的CreateServiceData对象中的ServiceInfo属性
ServiceInfo serviceInfo = (ServiceInfo) RefInvoke.getFieldValue(RefInvoke.getField(object.getClass(), “info”), object);
String hostServiceName = serviceInfo.name;
String pluginServiceName = HostToPluginMapping.getPluginService(hostServiceName);
if (TextUtils.isEmpty(pluginServiceName)) {
Log.i(TAG, “not found host service,so no need replace”);
return;
}
String path = DePluginSP.getInstance(DePluginApplication.getContext()).getString(Constants.COPY_FILE_PATH, “”);
面试是一个不断学习、不断自我提升的过程,有机会还是出去面面,至少能想到查漏补缺效果,而且有些知识点,可能你自以为知道,但让你说,并不一定能说得很好。
有些东西有压力才有动力,而学到的知识点,都是钱(因为技术人员大部分情况是根据你的能力来定级、来发薪水的),技多不压身。
附上我的面试各大专题整理: 面试指南,满满的都是干货,希望对大家有帮助!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
这里获取](https://bbs.csdn.net/topics/618156601)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。