zoukankan      html  css  js  c++  java
  • Android热修复之

    1.1 基本介绍
     
      我们先去github上面了解它https://github.com/alibaba/AndFix

    这里就有一个概念那就AndFix.apatch补丁用来修复方法,接下来我们看看到底是怎么实现的。

      
    1.2 生成apatch包
      
      假如我们收到了用户上传的崩溃信息,我们改完需要修复的Bug,这个时候就会有一个新的的apk我们就叫它为new.apk,原来的那个有Bug的apk你也有我们就叫它old.apk。这个时候我们就可以利用阿里github上面提供的工具生成一个xxxx.apatch包用于修复Bug。

    命令是:apkpatch.bat -f <new> -t <old> -o <output> -k <keystore> -p <> -a <alias> -e <>

    -f : 没有Bug的新版本apk
    -t : 有bug的旧版本apk
    -o : 生成的补丁文件所放的文件夹
    -k : 签名打包密钥
    -p : 签名打包密钥密码
    -a : 签名密钥别名
    -e : 签名别名密码(这样一般和密钥密码一致)

    我的是这样子:

    apkpatch.bat -f new.apk -t old.apk -o out -k joke.jks -p 240336124 -a 内涵段子 -e 240336124

    生成的补丁:

    1.3 修复apatch包

    怎么获取apatch包呢?我们肯定是请求接口获取下载我们的修复好的apatch包,当然有可能没有就太好了佛祖保佑。下载下来之后我们就可以调用方法进行修复了,我们可以暂时放在本地测试一下,这些代码肯定之前就得写好:

    public class BaseApplication extends Application {
        // Patch管理类
        public static PatchManager mPatchManager;
    
        @Override
        public void onCreate() {
            super.onCreate();
            // 捕捉崩溃信息
            ExceptionCrashHandler.getInstance().init(this);
    
            // Ali热修复
            try {
                mPatchManager = new PatchManager(this);
                // 初始化patch版本
                String pkName = this.getPackageName();
                String versionName = getPackageManager().getPackageInfo(pkName, 0).versionName;
                // 初始化版本名称
                mPatchManager.init(versionName);
                // 加载之前的patch
                mPatchManager.loadPatch();
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    主页面MainActivity
     1 public class MainActivity extends BaseSkinActivity {
     2 
     3     @Override
     4     protected void initData() {
     5         // 获取上次的崩溃信息
     6         File crashFile = ExceptionCrashHandler.getInstance().getCrashFile();
     7         // 上传到服务器,后面再说.......
     8     }
     9 
    10     @Override
    11     protected void initView() {
    12 
    13     }
    14 
    15     @Override
    16     protected void setContentView() {
    17         setContentView(R.layout.activity_main);
    18     }
    19 
    20     @Override
    21     protected void initTitle() {
    22 
    23     }
    24 
    25     @Onclick(R.id.test)
    26     public void test(View view) {
    27         // 没有修复之前会报异常闪退
    28         Toast.makeText(this, Utils.test(), Toast.LENGTH_LONG).show();
    29     }
    30 
    31     @Onclick(R.id.ali_fix)
    32     public void aliHotFix(View view) {
    33         try {
    34             // 测试 目前暂且放在本地
    35             String patchFileString =  Environment.getExternalStorageDirectory()+"/fix.apatch";
    36             Log.e("TAG", patchFileString);
    37             // 修复apatch,不需要重启可立即生效
    38             BaseApplication.mPatchManager.addPatch(patchFileString);
    39             Toast.makeText(this, "Bug修复成功", Toast.LENGTH_LONG).show();
    40         } catch (Exception e) {
    41             e.printStackTrace();
    42             Toast.makeText(this, "Bug修复失败", Toast.LENGTH_LONG).show();
    43         }
    44     }
    45 }

    运行的效果就在最上面,如果直接点击测试会报异常闪退,当我们点击完阿里开源热修复后再次点击测试,发现不闪退了。接下来的内容你可能要看不懂了请做好准备。

    1.4 正式开发需要注意的地方:

    1.每次生成之后一定要测试;
    2.尽量的不要分包,不要分多个dex
    3.混淆的时候,设计到NDK   AndFix.java 不要混淆
    4.生成包之后一般会加固什么的,这个时候生成的差分包,一定要在之前去生成。
    5.既然是去修复方法,第一个不能增加成员变量,不能增加方法
     
  • 相关阅读:
    mysql日期加减
    cron 配置计划任务的书写格式(quartz 时间配置)
    空值排序问题
    update 表名 set 字段=值,数据更新
    insert into 数据插入
    SQL里面的char类型
    SQL使用代码创建数据完整性,约束
    SQL制表
    sql创建数据库
    验证码
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/8184554.html
Copyright © 2011-2022 走看看