android 热修复第三方,android SDK热修复机制简析以实现

关于android 热修复,网上资料林林总总,比如AndFix、HotFix、DroidFix、Tinker等,这些都是从apk层面来实现怎么对线上app进行热修复的;但是有时候我们不仅仅需要热修复apk,当接入第三方SDK(jar)的话,获取也对需要SDK进行热修复,毕竟如果SDK有bug的话,APK替换修复好的SDK,然后发布新的版本代价太大。目前正好手头有这个需求,就查看资料捣鼓了一下,以博客的形式记录下来,供以后查看翻阅

SDK的热修复原理比App的热修复简单的多,核心原理或者步骤简单来说就两条:

1)下载服务器的jar

2)通过反射机制加载jar,创建相关对象并且操作之。

原理很简单,但是真正实现起来也有好几点需要注意:

1)宿主Apk配置上网以及SDK读写权限:

2)提供的jar包需要处理成dex格式的jar包,处理的步骤如下:

2.1)把打包好的jar放入android安装目录的platform-tools文件目录下(当然其他盘的任何目录都可以)。

2.2)cd 到android安装目录的build-tools文件如图:

51b087d73ee8f63e7a21cda4b34ef1bc.png

在此我选择23.0.0版本的文件夹:在该文件夹下有dx.bat和\lib\dx.jar两个文件,这两个文件正式转成dex格式的jar文件所需的工具。打开cmd,切换到23.0.0目录执行如下命令即可:dx - -dex - -output=转换后.jar,转换前.jar

c50d50b62a1f11bc3ace00919023c99a.png

如此就把jar转换成DexClassLoader可以加载的dex格式的jar了(hotfix.jar)。然后就可以交给宿主APK使用了。

3) 宿主Apk通过DexClassLoader加载hotfix.jar,通过反射创建对象并使用之。

为了方便说明,在此不实现jar的下载逻辑了,直接把hotfix.jar放在sdk卡根目录测试。

3.1)通过反射机制创建对象并使用之,代码如下:

private Object instance;// 反射形式创建的全局变量

private File file;//获取jar文件

private File dexOutputDir;

private DexClassLoader classLoader;

private Class sdkClass;

public void method1() {

file = new File(Environment

.getExternalStorageDirectory().toString()

+ File.separator

+ "hotfix.jar");

dexOutputDir = getDir("dex", 0);

classLoader = new DexClassLoader(file.getAbsolutePath(),

dexOutputDir.getAbsolutePath(), null, getClassLoader());

//加载sdk中提供的一个接口实现类

sdkClass = classLoader.loadClass("cn.com.hotfix.intefimpl.HotFixImpl");

//通过反射创建对象

instance = sdkClass.newInstance();

//通过反射获取hotFix方法

Method method = sdkClass.getMethod("hotFix", null);

//调用hotFix方法,并且获取hotFix方法返回的字符串;

String src = (String) method.invoke(instance, null);

Toast.makeText(MainActivity.this, src,

Toast.LENGTH_SHORT).show();

} catch (Exception exception) {

// Handle exception gracefully here.

exception.printStackTrace();

}

}

此种方式通过反射机制创建一个对象,并且通过反射机制创建对象,然后通过反射机制获取Method方法来完成业务逻辑。当然这种方法很麻烦,你得告诉宿主apk的方法的名称(比如上面的,参数的类型),主要是代码维护起来麻烦!所以也可以采用第二种方式:插件化方式给宿主提供jar!

3.2)反射机制+插件化的方式

这种方式仍然离不开反射机制,这个暂且不提;先说说插件化的要求:

宿主定制好所需接口,SDK实现该接口;这样当宿主apk引入第三方SDK的时候,结合反射机制,能很好的来对接SDK.下面以一个简单的demo来作说明。

第一步:宿主定制接口:

d4814ec93deca0a951e4ce558d3c917d.png

如图所示,HotFixSuZhu创建了cn.com.hotfix.interf.IHotFix的接口,该接口很简单:

public interface IHotFix {

public String hotFix();

}

现在宿主Apk已经定制好接口,那么SDK实现这个接口,然后打包成dex格式的jar提供给宿主使用就可以了!SDK结构如下:

fc0814113ec742849de6171137c66d5c.png

SDK同样需要创建一个cn.com.hotfix.interf包,该包下面同样需要创建跟宿主一模一样的IHotFix接口,这点从接入方式来看有点像AIDL客户端的使用方式:在使用AIDL的时候同样需要在客户端引入AIDL接口的全限定名以及接口文件。同时SDK的HotFixImpl实现了IHotFix接口:

public class HotFixImpl implements IHotFix {

@Override

public String hotFix() {

return "hotFix test";

}

}

到此为止,宿主接口创建好了,SDK也实现了宿主创建的接口;那么就看看宿主怎么使用SDK(注意SDK在打包成jar并转换成dex格式的时候:切记不要把SDK项目下的cn.com.hotfix.interf.IHotFix也打包):

private IHotFix hotFixImpl;//创建对象

private File file;//获取jar文件

private File dexOutputDir;

private DexClassLoader classLoader;

private Class sdkClass;

public void method1() {

file = new File(Environment

.getExternalStorageDirectory().toString()

+ File.separator

+ "hotfix.jar");

dexOutputDir = getDir("dex", 0);

classLoader = new DexClassLoader(file.getAbsolutePath(),

dexOutputDir.getAbsolutePath(), null, getClassLoader());

//加载sdk中提供的一个接口实现类

sdkClass = classLoader.loadClass("cn.com.hotfix.intefimpl.HotFixImpl");

//创建对象

hotFixImpl = (IHotFix) sdkClass.newInstance();

Toast.makeText(MainActivity.this, hotFixImpl.hotFix(),

Toast.LENGTH_SHORT).show();

}

到此位置,SDK的热更新机制使用完毕,无非就是远程加载sdk,利用反射机制来创建一个SDK的对象来完成工作。这种更新机制可用于于及时解决线上app第三方SDK出现的bug,避免apk重新发布让用户下载安装的这种不好的体验。

相对于SDK热修复的原理来说,此篇博文倒是显得啰嗦了,希望对大家有所帮助。不当之处或者有什么别的实现方式,欢迎交流。(点此下载demo)

今天闲着没事翻阅《android内核剖析这本书》的时候才发现原来此书也有关于android插件化开发的说明,详见该书第二章《java基础》篇的DexClassLoader的介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值