Android热修复(2):AndFix热修复框架的使用
AndFix的github地址
AndFix
AndFix是一个在线修复bug的解决方案,而不是重新发布Android应用程序。它是以Android库的形式发布的。
Andfix是“Android热修复”的缩写。
AndFix支持Android版本从2.3到7.0,ARM和X86架构,Dalvik和ART runtime, 32位和64位。
AndFix补丁的压缩文件格式是.apatch。它从您自己的服务器发送到客户端,以修复应用程序的错误。
原理
AndFix的原理就是方法的替换,把有bug的方法替换成补丁文件中的方法,AndFix只能修复方法级别的bug。
使用教程
1.添加依赖
dependencies {compile 'com.alipay.euler:andfix:0.5.0@aar'}
AndFixPatchManager:对Andfix进行封装
/** * Created by xiaoyehai on 2018/11/26 0026. * 管理AndFix所有的api */public class AndFixPatchManager { private static AndFixPatchManager mInstance = null; private PatchManager mPatchManager = null; public static AndFixPatchManager getInstance() { if (mInstance == null) { synchronized (AndFixPatchManager.class) { if (mInstance == null) { mInstance = new AndFixPatchManager(); } } } return mInstance; } /** * 初始化AndFix * * @param context */ public void initPatch(Context context) { mPatchManager = new PatchManager(context); mPatchManager.init(getVersionName(context)); mPatchManager.loadPatch(); } /** * 加载patch文件 * * @param path */ public void addPatch(String path) { if (mPatchManager != null) { try { mPatchManager.addPatch(path); } catch (IOException e) { e.printStackTrace(); } } } /** * 获取应用程序版本名称信息versionName * * @param context * @return 当前应用的版本名称 */ public static String getVersionName(Context context) { try { PackageManager packageManager = context.getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); return packageInfo.versionName; } catch (Exception e) { e.printStackTrace(); } return null; }}
2.初始化AndFix
public class AndFixApplication extends Application { @Override public void onCreate() { super.onCreate(); //初始化AndFix initAndFix(); } private void initAndFix() { AndFixPatchManager.getInstance().initPatch(this); }}
3.先准备一个有bug的release版apk:old.apk
public class MainActivity extends AppCompatActivity { //补丁文件后缀名 private static final String FILE_END = ".apatch"; //apatch文件路径 private String mPatchDir; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mPatchDir = getExternalCacheDir().getAbsolutePath() + "/apatch/"; //创建文件夹 File file = new File(mPatchDir); if (file == null || !file.exists()) { file.mkdir(); } } /** * 产生bug代码 * * @param view */ public void creatBug(View view) { String[] array = {"00", "11", "22", "33"}; Toast.makeText(this, array[4], Toast.LENGTH_SHORT).show(); //数组越界 } /** * 点击按钮加载补丁文件,修复bug * 项目中可以在下载补丁文件之后调用,这里为了演示就把补丁文件放在本地的SD卡中了 * * @param view */ public void fixBug(View view) { AndFixPatchManager.getInstance().addPatch(getPatchName()); Toast.makeText(this, "修复了bug", Toast.LENGTH_SHORT).show(); } /** * 获取patch文件路径 * * @return */ private String getPatchName() { //AndFix:apatch文件名 return mPatchDir.concat("AndFix").concat(FILE_END); }}
4.修复bug后的release版apk:new.apk
public void creatBug(View view) { String[] array = {"00", "11", "22", "33"}; Toast.makeText(this, array[3], Toast.LENGTH_SHORT).show(); //修复bug后代码 }
5.使用apkpatch-1.0.3.jar工具用命令生成.apatch文件
apkpatch-1.0.3.jar工具可以在github官网下载。
进入apkpatch-1.0.3文件夹文件夹,使用如下命令生成补丁.apatch文件:
apkpatch.bat -f new.apk -t old.apk -o outputs -k lantu.jks -p 123456 -a lantu -e 123456apkpatch.bat -f 新apk -t 旧apk -o 输出目录 -k app签名文件 -p 签名文件密码 -a 签名文件别名 -e 别名密码
命令行参数说明:
生成的.apatch文件:
5.修复测试
把补丁文件放入内存卡中,发现bug已经被修复。
实际开发中把补丁文件从服务器下载下来,自动加载补丁文件,修复bug。
注意每次appversion变更都会导致所有补丁被删除,如果appversion没有改变,则会加载已经保存的所有补丁。
在需要的地方调用PatchManager的addPatch方法加载新补丁,比如可以在下载补丁文件之后调用。
AndFix在服务中实现
步骤:
1.检查服务端是否有新的apatch文件
2.有:下载apatch文件
3.加载下载好的apatch文件,修复bug
/** * Created by xiaoyehai on 2018/11/27 0027. * 1.检查服务端是否有新的apatch文件 * 2.有:下载apatch文件 * 3.加载下载好的apatch文件,修复bug */public class AndFixService extends Service { public static final String TAG = AndFixService.class.getSimpleName(); private static final int DOWNLOAD_APATCH = 0x01; private static final int UPDATE_APATCH = 0x02; public static final String UPDATE_PATCH_URL = ""; public static final String DOWNLOAD_PATCH_URL = ""; //存放apatch文件的目录 private String mPatchFileDir; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case DOWNLOAD_APATCH: //下载apatch文件 downloadPatch(); break; case UPDATE_APATCH: //检查服务端是否有新的apatch文件 checkApatchUpdate(); break; } } }; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); init(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { mHandler.sendEmptyMessage(UPDATE_APATCH); return START_NOT_STICKY; //服务被系统回收之后不会自动重启 } private void init() { mPatchFileDir = getExternalCacheDir().getAbsolutePath() + "/apatch/"; File patchDir = new File(mPatchFileDir); try { if (patchDir == null || !patchDir.exists()) { patchDir.mkdirs(); } } catch (Exception e) { e.printStackTrace(); stopSelf(); //停止服务 } } /** * 检查服务端是否有新的apatch文件 */ private void checkApatchUpdate() { //获取服务器信息,判断是否有新的apatch文件 OkHttpManager.getInstance().asyncJsonStringByURL(UPDATE_PATCH_URL, new OkHttpManager.StringCallback() { @Override public void onResponse(String result) { //有新的apatch文件,下载文件 mHandler.sendEmptyMessage(DOWNLOAD_APATCH); } @Override public void onFailure(IOException e) { stopSelf(); } }); } /** * 下载apatch文件 */ private void downloadPatch() { DownloadManager.getInstance().downloadFile(DOWNLOAD_PATCH_URL, mPatchFileDir, new DownloadManager.FileCallback() { @Override public void onSuccess(File file) { //文件下载成功,加载apatc文件,修复bug AndFixPatchManager.getInstance().addPatch(file.getAbsolutePath()); } @Override public void onProgress(int progress, long total) { Log.e(TAG, "onProgress: " + progress); } @Override public void onError(Call call, Exception e) { stopSelf(); } }); }}
在app启动页面启动服务:
//启动服务Intent inten = new Intent(this, AndFixService.class);startService(inten);
Android热修复(1):热修复的介绍和原理解析
Android热修复(3):Tinker的使用
更多相关文章
- 开发可统计单词个数的Android驱动程序(1)
- 创建Android库的方法及Android(安卓).aar文件用法小结
- android中adb命令大全
- android adb shell 命令大全
- Android(安卓)adb shell 命令大全
- android aapt (android asset packaging tool)使用详解
- Android(安卓)adb shell 命令大全
- android的init.rc文件的语法
- android adb shell 命令大全