android 热修复

在网上看到很多热修复的文章,由于本人水平有限,在这里只讲解流程以及怎么实现,原理自己在网上找吧。
热修复方案有很多,比较有名的就是阿里巴巴的dexposed,AndFix以及QQ的Dex分包方案HotFix,Nuwa,DroidFix,在这里讲下AndFix和Nuwa的使用。
在使用这两个热修复框架之前先简单介绍下:

  AndFix:全称是Android hot-fix。是阿里开源的一个Android热补丁框架,允许APP在不重新发布版本的情况下修复线上的bug。支持Android 2.3 到 6.0。

  Nuwa:Nuwa,采用纯Java实现,能够热修复你的Android应用.

1.Nuwa的实现(注意:nuwa打出来的patch.jar在手机本地不能删除,如果删除则app又会回到之前有bug的状态):
第一步:在AndroidManifest中添加权限uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE” 。
第二步:在工程的根目录的build.gradle文件中的dependencies中添加 classpath ‘cn.jiajixin.nuwa:gradle:1.2.2’,如下图
这里写图片描述
第三步:在app的build.gradle中添加依赖SDK:compile ‘cn.jiajixin.nuwa:nuwa:1.0.0’和apply plugin: “cn.jiajixin.nuwa”如下图:
这里写图片描述
好了我们的配置就完了,但是可能你会报Error:Cannot get property ‘taskDependencies’ on null object这样的错误,其解决方法是将Gradle Plugin的版本降低至1.2.3就可以了,当然Gradle Version也要相应的降低至2.8。如下图:

这里写图片描述

这里写图片描述
下面就是使用nuwa了:
第四步:使用nuwa开始热更新代码的编写
MainActivity:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
private TextView textView;
    BugClass bugClass;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView  = (TextView)findViewById(R.id.hello);
        bugClass = new BugClass();
        textView.setText(bugClass.bug());
    }
}

BugClass:

  public class BugClass {
    String bug(){
        return "f";
    }
  }

BaseApplication:

public class BaseApplication extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        Nuwa.init(this);
        Nuwa.loadPatch(this, Environment.getExternalStorageDirectory().getAbsolutePath().concat("/patch.jar"));
        Log.e("nuwa",Environment.getExternalStorageDirectory().getAbsolutePath().concat("/patch.jar"));
    }
}

一定要记得在清单文件中写上android:name=”.BaseApplication”,不然不会加载差分包。如下图:
这里写图片描述
在这里我们要注意下:
这里有个需要注意的地方是自定义Application必须是直接继承自Application的类,如若自定义类AClazz继承自Application,又自定义类BClazz继承自AClazz并在注册表声明为BClazz,那么就会出现以下异常。也就是我们的初始化操作必须放在直属继承Application的AClazz当中。如下图:
这里写图片描述
第五步:运行app
注意:运行过程中可能会中途报错Execution failed for task ‘app:nuwaClassBeforeDexDebug’并在控制台将会输出以下信息
这里写图片描述
为解决以上遇到的问题,我们需要在app底下的build.gradle中加入multiDexEnabled true,如下图:
这里写图片描述
运行完app,在app\build\output目录下复制nuwa文件夹到任意位置,例如C:\nuwa,可以再项目工作空间复制也可以在studio中复制:
这里写图片描述
现在我们手机运行的是有bug的app,现在我们需要打patch.jar包放在手机根目录去修复这个bug,也就是和我们说的热修复(注:我这里是为了方便在sd卡中放patch.jar,在项目中你就要从你们的服务器中下载patch.jar)。
第六步:首先赶紧把你的有bug的地方改了(在这里我是把BugClass中返回的数值改了),看到别的文章建议是在执行命令前都应该先Clean以下项目(app\bulid\outputs\ 内容将重置),那我们就clear下,然后执行命令:
运行cmd–>切换到项目根目录(根目录下存在gradlew与gradlew.bat两个文件)–>执行命令(因为没有mac,所以…,但是windows亲测可以):
Mac:gradlew clean nuwaDebugPatch -P NuwaDir=C:\nuwa
Windows:gradlew.bat clean nuwaDebugPatch -P NuwaDir=C:\nuwa
然后就ok啦,去app\build\outputs\nuwa\debug目录下找到patch.jar文件,将这个文件放到手机sd卡根目录中,重新启动app就可以看到你刚才改的效果了。但是注意:在执行 Mac:gradlew clean nuwaDebugPatch -P NuwaDir=C:\nuwa
Windows:gradlew.bat clean nuwaDebugPatch -P NuwaDir=C:\nuwa命令时可能会出现这样的错误:
这里写图片描述
不要着急,我们在cdm命令中输入set ANDROID_HOME=D:/android/sdk ,等号后面的是你的sdk路径,执行完此命令然后再执行一遍 Mac:gradlew clean nuwaDebugPatch -P NuwaDir=C:\nuwa
Windows:gradlew.bat clean nuwaDebugPatch -P NuwaDir=C:\nuwa
,看看是否还会出现刚才的问题,不会出现啦(注意:你在执行命令之前一定要把你的bug改了,不然不会出现patch.jar),现在去app\build\outputs\nuwa\debug文件夹下找到patch.jar,将patch.jar放到sd卡根目录下,赶紧重启app见证奇迹吧。

2.AndFix的实现
第一步:在清单文件中加
uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”

uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”

在清单文件Application中加 android:name=”.AppContext”
这里写图片描述

第二步:
在app的build.gradle文件的dependencies中加:

compile 'com.alipay.euler:andfix:0.3.1@aar'

第三步:写代码:
AppContext.java:

public class AppContext extends Application {
    String apatch_path = "/out.apatch";
    String path_all = "";
    private PatchManager patchManager;

    @Override
    public void onCreate() {
        super.onCreate();
        patchManager = new PatchManager(this);//初始化 PatchManager
        patchManager.init(BuildConfig.VERSION_CODE + "");
        patchManager.loadPatch();//Load patch 加载补丁
        try {
            path_all = "/sdcard" + apatch_path;

            File file = new File(path_all);
            if (file.exists()) {
                Log.e("path exists" , file.getPath());
                patchManager.addPatch(path_all);//Add patch 添加补丁
            } else {
                Log.e("path unexists", path_all + "========");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

MainActivity.java:

public class MainActivity extends AppCompatActivity {
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textview);
        setTextFixAfter();
    }

    private void setTextFixAfter() {
        textView.setText("andfix热修复之前");
    }
}

第四步:下载工具:AndFix 提供了一个补丁创建工具 apkpatch
如何使用这个工具:

1.将下载的apkpatch.zip工具解压在某一个文件夹。
2.准备两个apk,一个是线上的apk,另一个是修复了bug的apk(测都这两个apk都是使用带签名的,不知道不带签名的会不会成功),将这两个apk放在apkpatch工具解压的文件夹下.
3.这个工程的签名文件*.jks也放在apkpatch工具解压的文件夹下.
4.执行命令apkpatch.bat -f -t -o -k -p <> -a -e <>

注意: 1.执行上述命令时,记得一定要cd到apkpatch-1.0.3目录下,然后再输入命令

这里写图片描述

这里是我的apkpatch解压目录(包含两个apk以及签名文件):
这里写图片描述
这里是我的命令:
这里写图片描述
第五步:在apkpatch工具解压的文件夹下有一个output文件夹,在这个文件夹中有一个.apath结尾的文件,修改这个文件的名字为out,即:out.apath.
第六步:手机上卸载你修改bug后的app,将修改bug前的apk放到sd卡上并且安装运行看效果,然后再把out.apatch文件放在手机sd卡根目录上,重启apk查看效果,看看和之前的效果是否一样,如果上述步骤正确,重启app后肯定是修改后的app的效果.

好了,Nuwa和Andfix热修复框架就讲解完了,有什么不对的请大家指出来,我们一起学习一起进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值