Robust热更应用在APP项目

由于项目中需要使用到美团的robust热更方案,所以写篇文章来记录一下使用步骤,以防忘记。官方提供的教程是将robust应用到APP项目中,我就先从app入手。
1、先在AS上面新建一个HotDemo APP,在App的build.gradle,加入如下依赖

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

compile 'com.meituan.robust:robust:0.4.78'

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

classpath 'com.meituan.robust:gradle-plugin:0.4.78'
classpath 'com.meituan.robust:auto-patch-plugin:0.4.78'

3、新建文件名为robust.xml(文件名不能修改)的文件,文件路径在app项目的根目录下,并将如下配置拷贝到文件中。




    
        
        
        true
        

        
        
        
        false

        
        
        
        false

        
        true
        

        
        
        false

        
        false
        

        
        true
        
    

    
    
    
        com.xy.demo
    

    
    
        com.meituan.robust
        com.meituan.sample.extension
    

    
    
        com.xy.demo
    

    
    

    


4、经robust.xml如下配置改为自己项目中需要插入代码的包名


    
    
        com.xy.demo
    

5、新建类PatchManipulateImp,代码中都有详细注释,如下

package com.xy.demo;

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
 *
 * 
* Pay attention to the difference of patch's LocalPath and patch's TempPath * *
* We recommend LocalPath store the origin patch.jar which may be encrypted,while TempPath is the true runnable jar *
*
* 我们推荐继承PatchManipulate实现你们App独特的A补丁加载策略,其中setLocalPath设置补丁的原始路径,这个路径存储的补丁是加密过得,setTempPath存储解密之后的补丁,是可以执行的jar文件 *
* setTempPath设置的补丁加载完毕即刻删除,如果不需要加密和解密补丁,两者没有啥区别 */ public class PatchManipulateImp extends PatchManipulate { /*** * connect to the network ,get the latest patches * l联网获取最新的补丁 * @param context * * @return */ @Override protected List 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.xy.demo.PatchesInfoImpl"); List patches = new ArrayList(); 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 { 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; } }

6、初始化robust

private void initRobust(){
        new PatchExecutor(this, new PatchManipulateImp(), new Callback()).start();
    }
    class Callback implements RobustCallBack {

        @Override
        public void onPatchListFetched(boolean result, boolean isNet, List patches) {
            Log.i("robust","robust arrived in onPatchListFetched");
        }

        @Override
        public void onPatchFetched(boolean result, boolean isNet, Patch patch) {
            Log.i("robust","robust arrived in onPatchFetched");
        }

        @Override
        public void onPatchApplied(boolean result, Patch patch) {
            Log.i("robust","robust arrived in onPatchApplied");

        }

        @Override
        public void logNotify(String log, String where) {
            Log.i("robust"," robust arrived in logNotify " + where);
        }

        @Override
        public void exceptionNotify(Throwable throwable, String where) {
            throwable.printStackTrace();
            Log.i("robust"," robust arrived in exceptionNotify " + where);
        }
    }

7、执行gradle命令生成APK,将生成好的APK安装到手机中。

gradlew clean  assembleRelease --stacktrace --no-daemon

8、将app根目录新建robust文件夹,并将app/build/outputs/robust/methodsMap.robust文件拷贝过去。
9、生成补丁,在代码有修改的方法上加入注解@Modify,如下:

    @Modify
    private String getData(){
        String data = "";
        for (int i=0;i<10;i++){
            data+=(i+"aaaaaaaaaaaaaaa");
        }
        return  data;
    }

10、将App的build.gradle 改为如下后再执行刚刚的gradl命令生成补丁。

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

11、执行gradle命令后报错没关系,有如下信息表示补丁生成成功了。

image.png

12、将补丁app\build\outputs\robust\patch.jar拷贝到手机目录,目录位置为PatchManipulateImp代码中设置的位置

//这里面需要设置一些补丁的信息,主要是联网的获取的补丁信息。重要的如MD5,进行原始补丁文件的简单校验,以及补丁存储的位置,这边推荐把补丁的储存位置放置到应用的私有目录下,保证安全性
        patch.setLocalPath(Environment.getExternalStorageDirectory().getPath()+ File.separator+"robust"+ File.separator + "patch");

你可能感兴趣的:(Robust热更应用在APP项目)