android 非侵入式热修复框架Hotfix使用

        先看一下比较热门的各大厂商热修复框架对比:

   


       

    Hotfix最新版本spofix是首款非侵入式框架:下面是百度内容

       假设大家都想要把用户代码塞到一个框架里。侵入式的做法就是要求用户代码知道框架的代码,表现为用户代码需要继承框   架提供的类。非侵入式则不需要用户代码引入框架代码的信息,从类的编写者角度来看,察觉不到框架的存在。
 
 例如:
  1)
使用struts的时候,我需要继承一些struts的类,这时struts侵入到了我的代码里。
  2)
使用spring,编写一些业务类的时候不需要继承spring特定的类,通过配置完成依赖注入后就可以使用,此时,spring就没     有侵入到我业务类的代码里。
  
 侵入式让用户代码产生对框架的依赖,这些代码不能在框架外使用,不利于代码的复用。但侵入式可以使用户跟框架更好的     结合,更容易更充分的利用框架提供的功能。
   
非侵入式的代码则没有过多的依赖,可以很方便的迁移到其他地方。但是与用户代码互动的方式可能就比较复杂。


 废话不多说直接看代码实现效果:

  1.直接在项目跟modle添加远程库:

     maven {    
     url "http://maven.aliyun.com/nexus/content/repositories/releases"  
      }

 整个截图:

 

   2.然后在app的build.gradle里面添加坐标版本依赖:

  1. compile'com.aliyun.ams:alicloud-android-hotfix:3.1.3'
注意,若SDK集成过程中出现UTDID冲突,请参考:阿里云-移动云产品SDK UTDID冲突解决方案
https://help.aliyun.com/knowledge_detail/59152.html
3.新建一个 Application(注意在清单文件中声明name属性)

完整application代码:
   import android.app.Application;

   import com.taobao.sophix.PatchStatus;
   import com.taobao.sophix.SophixManager;
   import com.taobao.sophix.listener.PatchLoadStatusListener;

   /**
   * Created by Administrator on 2017/10/23.
   * code: 1 补丁加载成功
   code: 6 服务端没有最新可用的补丁
   code: 11 RSASECRET错误,官网中的密钥是否正确请检查
   code: 12 当前应用已经存在一个旧补丁, 应用重启尝试加载新补丁
   code: 13 补丁加载失败, 导致的原因很多种, 比如UnsatisfiedLinkError等异常, 此时应该严格检查logcat异常日志
   code: 16 APPSECRET错误,官网中的密钥是否正确请检查
   code: 18 一键清除补丁
   code: 19 连续两次queryAndLoadNewPatch()方法调用不能短于3s
   */

   public class A extends Application {
    @Override
    public void onCreate() {
        SophixManager.getInstance().setContext(this)
                .setAppVersion("1.0.0")//你的后台版本
                .setAesKey(null)
                .setEnableDebug(true)
                .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                    @Override
                    public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
                        // 补丁加载回调通知
                        if (code == PatchStatus.CODE_LOAD_SUCCESS) {
                            // 表明补丁加载成功
                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                            // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启;
                            // 建议: 用户可以监听进入后台事件, 然后调用killProcessSafely自杀,以此加快应用补丁,详见1.3.2.3
                        } else {
                            // 其它错误信息, 查看PatchStatus类说明
                        }
                        

                    }
                }).initialize();
        // queryAndLoadNewPatch不可放在attachBaseContext 中,否则无网络权限,建议放在后面任意时刻,如onCreate中
        super.onCreate();
        SophixManager.getInstance().queryAndLoadNewPatch();
     }
   }

后台版本:此版本号一定要与 setAppVersion("1.0.0")一致

4.清单文件配置:
    
    
  1. <! -- 网络权限 -->
  2. <uses-permission android:name="android.permission.INTERNET" />
  3. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  4. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  5. <! -- 外部存储读权限,调试工具加载本地补丁需要 -->
  6. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

READ_EXTERNAL_STORAGE权限属于Dangerous Permissions,仅调试工具获取外部补丁需要,不影响线上发布的补丁加载,调试时请自行做好 android6.0以上的运行时权限获取。

AndroidManifest.xml中间的application节点下添加如下配置:

    
    
  1. <meta-data
  2. android:name="com.taobao.android.hotfix.IDSECRET"
  3. android:value="App ID" />
  4. <meta-data
  5. android:name="com.taobao.android.hotfix.APPSECRET"
  6. android:value="App Secret" />
  7. <meta-data
  8. android:name="com.taobao.android.hotfix.RSASECRET"
  9. android:value="RSA密钥" />

将上述value中的值分别改为通过平台HotFix服务申请得到的App Secret和RSA密钥

混淆配置

    
    
  1. #基线包使用,生成mapping.txt
  2. -printmapping mapping.txt
  3. #生成的mapping.txt在app/buidl/outputs/mapping/release路径下,移动到/app路径下
  4. #修复后的项目使用,保证混淆结果一致
  5. #-applymapping mapping.txt
  6. #hotfix
  7. -keep class com.taobao.sophix.**{*;}
  8. -keep class com.ta.utdid2.device.**{*;}
  9. #防止inline
  10. -dontoptimize

         以上便是spofix的集成步骤,是不是挺简单啊!!!!!!!

         测试部分:

         MianActivity中只写了一个战狼2的吐司

         


         注意一定是正式的打包签名完成后生成的apk文件哦!

         效果图:

         

         

        现在将战狼2更改为杀破狼.贪狼并将Helloworld背景颜色更改

        

        

         更改完毕后生成新的release apk文件

         两个apk文件不要弄混了

         

        

       然后下载补丁生成工具:https://help.aliyun.com/document_detail/53247.html?spm=5176.2020520107.0.0.e0fc1a1tRrvPT

       



          解压后得到一个SophixPatchTool.exe文件 注意要JDK7以上版本支持

          双击打开选择刚才生成的基准版本与更新版本apk,如下图:

          


         注意设置按钮里面的设置:

         


        完事后:

        


       然后将生成的补丁文件上传到阿里的开发后台:

      

       

       上传完毕后查看详情直接选择灰度下发:官方提示说要本地扫码验证后在灰度下发 我     试了几下没成功就直接跳过了 

        看运行效果:

        


        调试:

        在applation中打个Log看PatchStatus的状态码分析问题

  

    这里列举几个常见的code码说明,

  • code: 1 补丁加载成功
  • code: 6 服务端没有最新可用的补丁
  • code: 11 RSASECRET错误,官网中的密钥是否正确请检查
  • code: 12 当前应用已经存在一个旧补丁, 应用重启尝试加载新补丁
  • code: 13 补丁加载失败, 导致的原因很多种, 比如UnsatisfiedLinkError等异常, 此时应该严格检查logcat异常日志
  • code: 16 APPSECRET错误,官网中的密钥是否正确请检查
  • code: 18 一键清除补丁
  • code: 19 连续两次queryAndLoadNewPatch()方法调用不能短于3s

详情查看SDK中PatchStatus类的代码,有具体说明:

    
    
  1. package com.taobao.sophix;
  2. public class PatchStatus {
  3. public final static int CODE_REQ_START = 0;
  4. public final static String INFO_REQ_START = "ready to start.";
  5. public final static int CODE_LOAD_SUCCESS = 1;
  6. public final static String INFO_LOAD_SUCCESS = "load new patch success.";
  7. public final static int CODE_ERR_NOTINIT = 2;
  8. public final static String INFO_ERR_NOTINIT = "didn't initialize hotfix sdk or initialize fail.";
  9. public final static int CODE_ERR_NOTMAIN = 3;
  10. public final static String INFO_ERR_NOTMAIN = "only allow query in main process.";
  11. public final static int CODE_ERR_INBLACKLIST = 4;
  12. public final static String INFO_ERR_INBLACKLIST = "current device does't support hotfix.";
  13. public final static int CODE_REQ_ERR = 5;
  14. public final static String INFO_REQ_ERR = "pull patch info detail fail, please check log.";
  15. public final static int CODE_REQ_NOUPDATE = 6;
  16. public final static String INFO_REQ_NOUPDATE = "there is not update.";
  17. public final static int CODE_REQ_NOTNEWEST = 7;
  18. public final static String INFO_REQ_NOTNEWEST = "the query patchversion equals or less than current patchversion, stop download.";
  19. public final static int CODE_DOWNLOAD_FAIL = 8;
  20. public final static int CODE_DOWNLOAD_SUCCESS = 9;
  21. public final static String INFO_DOWNLOAD_SUCCESS = "patch download success.";
  22. public final static int CODE_DOWNLOAD_BROKEN = 10;
  23. public final static String INFO_DOWNLOAD_BROKEN = "patch file is broken.";
  24. public final static int CODE_UNZIP_FAIL = 11;
  25. public final static String INFO_UNZIP_FAIL = "unzip patch file error, please check value of AndroidMenifest.xml RSASECRET or initialize param aesKey.";
  26. public final static int CODE_LOAD_RELAUNCH = 12;
  27. public final static String INFO_LOAD_RELAUNCH = "please relaunch app to load new patch.";
  28. public final static int CODE_LOAD_FAIL = 13;
  29. public final static String INFO_LOAD_FAIL = "load patch fail, please check stack trace of an exception: ";
  30. public final static int CODE_LOAD_NOPATCH = 14;
  31. public final static String INFO_LOAD_NOPATCH = "do not found any patch file to load.";
  32. public final static int CODE_REQ_APPIDERR = 15;
  33. public final static String INFO_REQ_APPIDERR = "appid is not found.";
  34. public final static int CODE_REQ_SIGNERR = 16;
  35. public final static String INFO_REQ_SIGNERR = "token is invaild, please check APPSECRET.";
  36. public final static int CODE_REQ_UNAVAIABLE = 17;
  37. public final static String INFO_REQ_UNAVAIABLE = "req is unavailable as has already been in arrearage.";
  38. public final static int CODE_REQ_CLEARPATCH = 18;
  39. public final static String INFO_REQ_CLEARPATCH = "clean client patch as server publish clear cmd.";
  40. public final static int CODE_REQ_TOOFAST = 19;
  41. public final static String INFO_REQ_TOOFAST = "two consecutive request should not short then 3s.";
  42. public final static int CODE_PATCH_INVAILD = 20;
  43. public static final String INFO_PATCH_INVAILD = "patch invaild, as patch not exist or is dir or not a jar compress file.";
  44. public final static int CODE_LOAD_FORBIDDEN = 21;
  45. public static final String INFO_LOAD_FORBIDDEN = "debuggable is false! forbid loading local patch for secure reason!";
  46. }

 

         

       

      


猜你喜欢

转载自blog.csdn.net/liu3364575/article/details/77677931