关于andfix热更新的配置

配置环境 Android studio 

1、在build.gradle中添加引用包

compile 'com.alipay.euler:andfix:[email protected]//官方最新的为0.5.0,但是在4.4版本中存在bug,推荐使用0.4.0
2、在Application中初始化
代码如下
 public static PatchManager mPatchManager;

    @Override
    public void onCreate() {
        super.onCreate();

        // 初始化patch管理类
        mPatchManager = new PatchManager(this);

        // 初始化patch版本
        mPatchManager.init("1.0");
//        String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
//        mPatchManager.init(appVersion);

        // 加载已经添加到PatchManager中的patch
        mPatchManager.loadPatch();

    }
3、混淆不能忘记
-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
    native <methods>;
}



4、设置补丁名称
private static final String APATCH_PATH = "/fix.apatch"; // 补丁文件名
5、下载补丁包
/**
 * 网络请求下载补丁包
 */
private class DownloadFileThread implements Runnable {
    @Override
    public void run() {
        try {
            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + APATCH_PATH);
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Accept-Encoding", "identity");
            long sum = 0;
            if (file.exists()) {
                file.delete();
                    /*sum = file.length();
                    // 设置断点续传的开始位置
                    connection.setRequestProperty("Range", "bytes=" + file.length() + "-");*/
            }
            int code = connection.getResponseCode();
            if (code == 200 || code == 206) {
                int contentLength = connection.getContentLength();
                contentLength += sum;
                InputStream is = connection.getInputStream();
            /*
            *
            * 创建一个向具有指定 name 的文件中写入数据的输出文件流。
            * true表示当文件在下载过程中出现中断,
            * 当再次链接网络时,将会从断点处追加。
            *
            * */
                if(Build.VERSION.SDK_INT>=23){
                    verifyStoragePermissions(MainActivity.this);
                }
                FileOutputStream fos = new FileOutputStream(file, true);
                byte[] buffer = new byte[1024];
                int length;
                while ((length = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, length);
                    sum += length;
                    percent = sum * 100.0f / contentLength;
                }
                update();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
6、加载补丁包
private void update() {
    String patchFileStr =Environment.getExternalStorageDirectory().getAbsolutePath() + APATCH_PATH;
    try {
        AndFixApplication.mPatchManager.addPatch(patchFileStr);
    } catch (IOException e) {
        e.printStackTrace();
    }

}
7、注意Android 6.0以上要动态设置读取权限
private static final int REQUEST_EXTERNAL_STORAGE = 1;
     private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE };

public static void verifyStoragePermissions(Activity activity) {
             // Check if we have write permission
             int permission = ActivityCompat.checkSelfPermission(activity,
                           Manifest.permission.WRITE_EXTERNAL_STORAGE);

            if (permission != PackageManager.PERMISSION_GRANTED) {
                     // We don't have permission so prompt the user
                     ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,
                                     REQUEST_EXTERNAL_STORAGE);
                 }
        }

8、准备打补丁
 设置button ,当点击button是提示一句话,用来和加载补丁之后做对比判断补丁是否加载成功
9、下载官方提供的工具
  https://github.com/alibaba/AndFix.git 找到apkpatch-1.0.3文件夹下载下来放到桌面
10、先打一个正式包
  放到下载好的apkpatch-1.0.3文件中设置一个名字。我设置的是andfix_v1.0
11、修改一处地方再打另一个正式包
 也放到下载好的 apkpatch-1.0.3文件中设置一个名字。我设置的是andfix_v2.0
12、把打包用的jks文件也放到这个文件中
 13、打开cmd命令窗口
 输入cd Desktop回车
再输入 cd apkpatch-1.0.3 回车

再输入 关于andfix热更新的配置
解释如下
  • -f <new.apk> :新apk
  • -t <old.apk> : 旧apk
  • -o <output> : 输出目录(补丁文件的存放目录)
  • -k <keystore>: 打包所用的keystore
  • -p <password>: keystore的密码
  • -a <alias>: keystore 用户别名
  • -e <alias password>: keystore 用户别名密码
在output中得到文件andfix_v2-64aef0866fcd3f5d7046716911b8cf52.apatch,然后改为和自己设置的文件名一致,然后放到服务器中。
我打补丁之前写的是提示的是打补丁之前,加载补丁之后提示打补丁之后
注意:
andfix 只能修改代码不能修改布局文件,不能替换资源文件,无法添加新类和新的字段
需要使用加固前的apk制作补丁,但是补丁文件很容易被反编译,也就是修改过的类源码容易泄露。
使用加固平台可能会使热补丁功能失效(看到有人在360加固提了这个问题,自己还未验证)。
应用patch不需要重启。但由于从实现上直接跳过了类初始化,设置为初始化完毕,所以像是静态函数、静态成员、构造函数都会出现问题,复杂点的类Class.forname很可能直接就会挂掉





'