Robust 热更新使用记录

1、添加依赖

a、在App的build.gradle,加入如下依赖

apply plugin: 'com.android.application'
//制作补丁时将这个打开,auto-patch-plugin紧跟着com.android.application
//apply plugin: 'auto-patch-plugin'
apply plugin: 'robust'
	
	
compile 'com.meituan.robust:robust:0.4.82'

b、在整个项目的build.gradle加入classpath

 buildscript {
    repositories {
        jcenter()
    }
    dependencies {
         classpath 'com.meituan.robust:gradle-plugin:0.4.82'
         classpath 'com.meituan.robust:auto-patch-plugin:0.4.82'
   }
}

c、在项目的src同级目录下配置robust.xml文件,具体项请参考DEMOapp/robust.xml

 

2、生成patch

a、拷贝文件

一定要开启混淆,否则不会生成map文件;需要 被修改版本的两个文件mapping文件和methodsMap.robust;

然后拷贝两个文件mapping文件和methodsMap.robust到和build同级的bobust文件夹下;官网上有一个hash文件,测试下拉,是没有使用到的;

b、修改代码

在改动的方法上面添加@Modify注解,对于Lambda表达式请在修改的方法里面调用RobustModify.modify()方法

 @Modify
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     }
     //或者是被修改的方法里面调用RobustModify.modify()方法
     protected void onCreate(Bundle savedInstanceState) {
        RobustModify.modify()
        super.onCreate(savedInstanceState);
     }

新增的方法和字段使用@Add注解

//增加方法
    @Add
    public String getString() {
        return "Robust";
    }
    //增加类
    @Add
    public class NewAddCLass {
        public static String get() {
           return "robust";
         }
    }

c、修改build文件

apply plugin: 'com.android.application'
//关闭'robust'并打开'auto-patch-plugin'
//apply plugin: 'robust'
apply plugin: 'auto-patch-plugin'

d、执行IDE中的编译apk文件操作,生成Patch

在build窗口中有上图提示 auto patch end successfully ,并且在build/outputs/robust/下有patch.jar就说明编译patch成功了;

3、使用patch

能使用patch必须在要修复的版本上能够该patch,在类中要调用

new PatchExecutor(getApplicationContext(), new PatchManipulateImp(), new RobustCallBackSample()).start();

其中 PatchManipulateImp是实现如何加载patch包括路径等问题;

RobustCallBackSample是演示加载成功失败等回调;
public class PatchManipulateImp extends PatchManipulate
package com.othershe.dutiltest;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.meituan.robust.Patch;
import com.meituan.robust.PatchManipulate;
import com.meituan.robust.RobustApkHashUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by mivanzhang on 17/2/27.
 *
 * We recommend you rewrite your own PatchManipulate class ,adding your special patch Strategy,in the demo we just load the patch directly
 *
 * <br>
 *   Pay attention to the difference of patch's LocalPath and patch's TempPath
 *
 *     <br>
 *    We recommend LocalPath store the origin patch.jar which may be encrypted,while TempPath is the true runnable jar
 *<br>
 *<br>
 *    我们推荐继承PatchManipulate实现你们App独特的A补丁加载策略,其中setLocalPath设置补丁的原始路径,这个路径存储的补丁是加密过得,setTempPath存储解密之后的补丁,是可以执行的jar文件
 *     <br>
 *     setTempPath设置的补丁加载完毕即刻删除,如果不需要加密和解密补丁,两者没有啥区别
 */

public class PatchManipulateImp extends PatchManipulate {
    private static final String TAG = "robust";
    /***
     * connect to the network ,get the latest patches
     * l联网获取最新的补丁
     * @param context
     *
     * @return
     */
    @Override
    protected List<Patch> fetchPatchList(Context context) {
        //将app自己的robustApkHash上报给服务端,服务端根据robustApkHash来区分每一次apk build来给app下发补丁
        //apkhash is the unique identifier for  apk,so you cannnot patch wrong apk.
        String robustApkHash = RobustApkHashUtils.readRobustApkHash(context);
        Log.w("robust","robustApkHash :" + robustApkHash);
        //connect to network to get patch list on servers
        //在这里去联网获取补丁列表
        Patch patch = new Patch();
        patch.setName("123");
        //we recommend LocalPath store the origin patch.jar which may be encrypted,while TempPath is the true runnable jar
        //LocalPath是存储原始的补丁文件,这个文件应该是加密过的,TempPath是加密之后的,TempPath下的补丁加载完毕就删除,保证安全性
        //这里面需要设置一些补丁的信息,主要是联网的获取的补丁信息。重要的如MD5,进行原始补丁文件的简单校验,以及补丁存储的位置,这边推荐把补丁的储存位置放置到应用的私有目录下,保证安全性
        patch.setLocalPath(Environment.getExternalStorageDirectory().getPath()+ File.separator+"robust"+File.separator + "patch");

        //setPatchesInfoImplClassFullName 设置项各个App可以独立定制,需要确保的是setPatchesInfoImplClassFullName设置的包名是和xml配置项patchPackname保持一致,而且类名必须是:PatchesInfoImpl
        //请注意这里的设置
        patch.setPatchesInfoImplClassFullName("com.othershe.dutiltest.patch.PatchesInfoImpl");
        List  patches = new ArrayList<Patch>();
        patches.add(patch);
        return patches;
    }

    /**
     *
     * @param context
     * @param patch
     * @return
     *
     * you can verify your patches here
     */
    @Override

    protected boolean verifyPatch(Context context, Patch patch) {
        //do your verification, put the real patch to patch
        //放到app的私有目录
        patch.setTempPath(context.getCacheDir()+ File.separator+"robust"+File.separator + "patch");
        //in the sample we just copy the file
        try {
            Log.w(TAG, "verifyPatch LocalPath: "+patch.getLocalPath() );
            Log.w(TAG, "verifyPatch TempPath : "+patch.getTempPath() );
            copy(patch.getLocalPath(), patch.getTempPath());
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("copy source patch to local patch error, no patch execute in path "+patch.getTempPath());
        }

        return true;
    }
    public void copy(String srcPath,String dstPath) throws IOException {
        File src=new File(srcPath);
        if(!src.exists()){
            throw new RuntimeException("source patch does not exist ");
        }
        File dst=new File(dstPath);
        if(!dst.getParentFile().exists()){
            dst.getParentFile().mkdirs();
        }
        InputStream in = new FileInputStream(src);
        try {
            OutputStream out = new FileOutputStream(dst);
            try {
                // Transfer bytes from in to out
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } finally {
                out.close();
            }
        } finally {
            in.close();
        }
    }
    /**
     *
     * @param patch
     * @return
     *
     * you may download your patches here, you can check whether patch is in the phone
     */
    @Override
    protected boolean ensurePatchExist(Patch patch) {
        return true;
    }
}
package com.othershe.dutiltest;

import android.util.Log;

import com.meituan.robust.Patch;
import com.meituan.robust.RobustCallBack;

import java.util.List;

/**
 * Created by hedingxu on 17/11/26.
 */
public class RobustCallBackSample implements RobustCallBack {

    @Override
    public void onPatchListFetched(boolean result, boolean isNet, List<Patch> patches) {
        Log.d("RobustCallBack", "onPatchListFetched result: " + result);
        Log.d("RobustCallBack", "onPatchListFetched isNet: " + isNet);
        for (Patch patch : patches) {
            Log.d("RobustCallBack", "onPatchListFetched patch: " + patch.getName());
        }
    }

    @Override
    public void onPatchFetched(boolean result, boolean isNet, Patch patch) {
        Log.d("RobustCallBack", "onPatchFetched result: " + result);
        Log.d("RobustCallBack", "onPatchFetched isNet: " + isNet);
        Log.d("RobustCallBack", "onPatchFetched patch: " + patch.getName());
    }

    @Override
    public void onPatchApplied(boolean result, Patch patch) {
        Log.d("RobustCallBack", "onPatchApplied result: " + result);
        Log.d("RobustCallBack", "onPatchApplied patch: " + patch.getName());

    }

    @Override
    public void logNotify(String log, String where) {
        Log.d("RobustCallBack", "logNotify log: " + log);
        Log.d("RobustCallBack", "logNotify where: " + where);
    }

    @Override
    public void exceptionNotify(Throwable throwable, String where) {
        Log.e("RobustCallBack", "exceptionNotify where: " + where, throwable);
    }
}

以上所有的都是从官网上查到的,只是加了自己的一些理解;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值