2015年以来,Android开发领域里对热修复技术的讨论和分享越来越多,同时也出现了一些不同的解决方案,如QQ空间补丁方案、阿里AndFix以及微信Tinker(Bugly sdk也集成Tikner热更新)和阿里最新出品Sophix.它们在原理各有不同,适用场景各异。不过从技术上来说多数热修复框架是基于ClassLoader加载机制。下面是常见热修复框架的比较。
开通热修复服务
读者可以打开Sophix热修复的官网:Sophix官网1、注册阿里云账号,选择移动热修复服务 ,选择之后需要开通此功能,点击立即开通即可。
2、打开管理控制台,点击右上角创建APP。
3、点击Hoxfix列表android版本的app后面的管理即可查看基本信息(AppId、AppSecret和密钥)。
本地接入热修复服务
1,添加依赖库和包
打开项目的app的build.gradle文件,添加maven仓库地址和hotfix库依赖:
repositories { maven { url "http://maven.aliyun.com/nexus/content/repositories/releases" } } dependencies { compile 'com.aliyun.ams:alicloud-android-hotfix:3.1.0' }
注:如果项目中也依赖其它阿里系SDK,可能会同时依赖了utdid这个SDK,为了避免冲突可以这样。
dependencies { compile ('com.aliyun.ams:alicloud-android-hotfix:3.1.0') { exclude(module:'alicloud-android-utdid') } }
2,AndroidManifest相关配置
在AndroidManifest配置文件中添加如下配置:
<!-- 网络权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 外部存储读权限,调试工具加载本地补丁需要 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
在application标签下添加如下信息:
1 <meta-data 2 android:name="com.taobao.android.hotfix.IDSECRET" 3 android:value="AppId" /> 4 <meta-data 5 android:name="com.taobao.android.hotfix.APPSECRET" 6 android:value="AppSecret" /> 7 <meta-data 8 android:name="com.taobao.android.hotfix.RSASECRET" 9 android:value="RSA密钥" />
3,在Application中初始化Sophix。
initialize的调用应该尽可能的早,必须在Application.attachBaseContext()或者Application.onCreate()的最开始进行SDK初始化操作,否则极有可能导致崩溃。而查询服务器是否有可用补丁的操作可以在后面的任意地方。
例如:
1 public class SophixApp extends Application { 2 3 @Override 4 public void onCreate() { 5 super.onCreate(); 6 initSophix(); 7 } 8 9 private void initSophix() { 10 String appVersion; 11 12 try { 13 appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; 14 } catch (PackageManager.NameNotFoundException e) { 15 appVersion = "1.0.0"; 16 e.printStackTrace(); 17 } 18 19 // initialize最好放在attachBaseContext最前面 20 SophixManager.getInstance().setContext(this) 21 .setAppVersion(appVersion) 22 .setAesKey(null) 23 .setEnableDebug(true) 24 .setPatchLoadStatusStub(new PatchLoadStatusListener() { 25 @Override 26 public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) { 27 // 补丁加载回调通知 28 if (code == PatchStatus.CODE_LOAD_SUCCESS) { 29 // 表明补丁加载成功 30 } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) { 31 // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启; 32 // 建议: 用户可以监听进入后台事件, 然后调用killProcessSafely自杀,以此加快应用补丁,详见1.3.2.3 33 } else { 34 // 其它错误信息, 查看PatchStatus类说明 35 } 36 } 37 }).initialize(); 38 // queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中 39 SophixManager.getInstance().queryAndLoadNewPatch(); 40 } 41 42 }
记得在AndroidManifest中使用我们自己的Application。
生成补丁并上传到控制台
1,为了简单,我们需要生成两个apk,两个apk做一个简单的内容区分即可。将第一个命名为old.apk,代码如下:
1 public class MainActivity extends AppCompatActivity { 2 3 private TextView mTextView; 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_main); 9 10 mTextView = (TextView) findViewById(R.id.textView); 11 mTextView.setText("版本修复前"); 12 13 } 14 }
将第二个命名为new.apk,内容如下:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv= findViewById(R.id.fix_text); tv.setText("版本修复后数据..."); Toast.makeText(this,"版本修复完成",Toast.LENGTH_LONG).show(); } }
2,生成补丁的话需要下载阿里的打补丁工具SophixPatchTool,选择对应的平台,然后分别选择两次打包生成的apk,点击go即可。
补丁生成后,上传到阿里云平台,版本信息和代码的versionName对应。
然后点击上传补丁即可。
在选择正式发布之前,官方建议您先进行本地测试。下载hotfixdebug工具安装后,填写包名,点击连接应用,然后扫描补丁详情中的二维码下载补丁。或者将补丁包放到手机sdcard,填写绝对路径也是可以的。
Mode:1 表示扫码模式, Code:12 表示应用当前已经有一个补丁, 所以新补丁不会立刻加载需要等下一次重启加载。
总结
Sophix的优点:
1、补丁可以即时生效,不需要应用重启(我测试的过程中是因为本地已经存在了,所以需要重启APP);
2、补丁包同样采用差量技术,生成的PATCH体积小,阿里采用自己的SophixPatchTool进行补丁生成,简单易用;
3、对应用无侵入,几乎无性能损耗;
4、傻瓜式接入。
缺点:
开始收费,不过有免费阈值,每月5万台设备免费。具体资费请查看:价格资费