AndFix的github地址

AndFix

AndFix是一个在线修复bug的解决方案,而不是重新发布Android应用程序。它是以Android库的形式发布的。

Andfix是“Android热修复”的缩写。

AndFix支持Android版本从2.3到7.0,ARM和X86架构,Dalvik和ART runtime, 32位和64位。

AndFix补丁的压缩文件格式是.apatch。它从您自己的服务器发送到客户端,以修复应用程序的错误。

原理

AndFix的原理就是方法的替换,把有bug的方法替换成补丁文件中的方法,AndFix只能修复方法级别的bug。

使用教程

1.添加依赖

dependencies {compile 'com.alipay.euler:andfix:0.5.0@aar'}

AndFixPatchManager:对Andfix进行封装

/** * Created by xiaoyehai on 2018/11/26 0026. * 管理AndFix所有的api */public class AndFixPatchManager {    private static AndFixPatchManager mInstance = null;    private PatchManager mPatchManager = null;    public static AndFixPatchManager getInstance() {        if (mInstance == null) {            synchronized (AndFixPatchManager.class) {                if (mInstance == null) {                    mInstance = new AndFixPatchManager();                }            }        }        return mInstance;    }    /**     * 初始化AndFix     *     * @param context     */    public void initPatch(Context context) {        mPatchManager = new PatchManager(context);        mPatchManager.init(getVersionName(context));        mPatchManager.loadPatch();    }    /**     * 加载patch文件     *     * @param path     */    public void addPatch(String path) {        if (mPatchManager != null) {            try {                mPatchManager.addPatch(path);            } catch (IOException e) {                e.printStackTrace();            }        }    }    /**     * 获取应用程序版本名称信息versionName     *     * @param context     * @return 当前应用的版本名称     */    public static String getVersionName(Context context) {        try {            PackageManager packageManager = context.getPackageManager();            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);            return packageInfo.versionName;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }}

2.初始化AndFix

public class AndFixApplication extends Application {    @Override    public void onCreate() {        super.onCreate();        //初始化AndFix        initAndFix();    }    private void initAndFix() {        AndFixPatchManager.getInstance().initPatch(this);    }}

3.先准备一个有bug的release版apk:old.apk

public class MainActivity extends AppCompatActivity {    //补丁文件后缀名    private static final String FILE_END = ".apatch";    //apatch文件路径    private String mPatchDir;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mPatchDir = getExternalCacheDir().getAbsolutePath() + "/apatch/";        //创建文件夹        File file = new File(mPatchDir);        if (file == null || !file.exists()) {            file.mkdir();        }    }    /**     * 产生bug代码     *     * @param view     */    public void creatBug(View view) {        String[] array = {"00", "11", "22", "33"};       Toast.makeText(this, array[4], Toast.LENGTH_SHORT).show(); //数组越界    }    /**     * 点击按钮加载补丁文件,修复bug     * 项目中可以在下载补丁文件之后调用,这里为了演示就把补丁文件放在本地的SD卡中了     *     * @param view     */    public void fixBug(View view) {        AndFixPatchManager.getInstance().addPatch(getPatchName());        Toast.makeText(this, "修复了bug", Toast.LENGTH_SHORT).show();    }    /**     * 获取patch文件路径     *     * @return     */    private String getPatchName() {        //AndFix:apatch文件名        return mPatchDir.concat("AndFix").concat(FILE_END);    }}

4.修复bug后的release版apk:new.apk

  public void creatBug(View view) {        String[] array = {"00", "11", "22", "33"};        Toast.makeText(this, array[3], Toast.LENGTH_SHORT).show(); //修复bug后代码    }

5.使用apkpatch-1.0.3.jar工具用命令生成.apatch文件

apkpatch-1.0.3.jar工具可以在github官网下载。

进入apkpatch-1.0.3文件夹文件夹,使用如下命令生成补丁.apatch文件:

apkpatch.bat -f new.apk -t old.apk -o outputs -k lantu.jks -p 123456 -a lantu -e 123456apkpatch.bat -f 新apk -t 旧apk -o 输出目录 -k app签名文件 -p 签名文件密码 -a 签名文件别名 -e 别名密码

命令行参数说明:

生成的.apatch文件:

5.修复测试

把补丁文件放入内存卡中,发现bug已经被修复。

实际开发中把补丁文件从服务器下载下来,自动加载补丁文件,修复bug。

注意每次appversion变更都会导致所有补丁被删除,如果appversion没有改变,则会加载已经保存的所有补丁。

在需要的地方调用PatchManager的addPatch方法加载新补丁,比如可以在下载补丁文件之后调用。

AndFix在服务中实现

步骤:

1.检查服务端是否有新的apatch文件
2.有:下载apatch文件
3.加载下载好的apatch文件,修复bug

/** * Created by xiaoyehai on 2018/11/27 0027. * 1.检查服务端是否有新的apatch文件 * 2.有:下载apatch文件 * 3.加载下载好的apatch文件,修复bug */public class AndFixService extends Service {    public static final String TAG = AndFixService.class.getSimpleName();    private static final int DOWNLOAD_APATCH = 0x01;    private static final int UPDATE_APATCH = 0x02;    public static final String UPDATE_PATCH_URL = "";    public static final String DOWNLOAD_PATCH_URL = "";    //存放apatch文件的目录    private String mPatchFileDir;    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what) {                case DOWNLOAD_APATCH: //下载apatch文件                    downloadPatch();                    break;                case UPDATE_APATCH: //检查服务端是否有新的apatch文件                    checkApatchUpdate();                    break;            }        }    };    @Nullable    @Override    public IBinder onBind(Intent intent) {        return null;    }    @Override    public void onCreate() {        super.onCreate();        init();    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        mHandler.sendEmptyMessage(UPDATE_APATCH);        return START_NOT_STICKY; //服务被系统回收之后不会自动重启    }    private void init() {        mPatchFileDir = getExternalCacheDir().getAbsolutePath() + "/apatch/";        File patchDir = new File(mPatchFileDir);        try {            if (patchDir == null || !patchDir.exists()) {                patchDir.mkdirs();            }        } catch (Exception e) {            e.printStackTrace();            stopSelf(); //停止服务        }    }    /**     * 检查服务端是否有新的apatch文件     */    private void checkApatchUpdate() {        //获取服务器信息,判断是否有新的apatch文件        OkHttpManager.getInstance().asyncJsonStringByURL(UPDATE_PATCH_URL, new OkHttpManager.StringCallback() {            @Override            public void onResponse(String result) {                //有新的apatch文件,下载文件                mHandler.sendEmptyMessage(DOWNLOAD_APATCH);            }            @Override            public void onFailure(IOException e) {                stopSelf();            }        });    }    /**     * 下载apatch文件     */    private void downloadPatch() {        DownloadManager.getInstance().downloadFile(DOWNLOAD_PATCH_URL, mPatchFileDir, new DownloadManager.FileCallback() {            @Override            public void onSuccess(File file) {                //文件下载成功,加载apatc文件,修复bug                AndFixPatchManager.getInstance().addPatch(file.getAbsolutePath());            }            @Override            public void onProgress(int progress, long total) {                Log.e(TAG, "onProgress: " + progress);            }            @Override            public void onError(Call call, Exception e) {                stopSelf();            }        });    }}

在app启动页面启动服务:

//启动服务Intent inten = new Intent(this, AndFixService.class);startService(inten);

Android热修复(1):热修复的介绍和原理解析

Android热修复(3):Tinker的使用

更多相关文章

  1. 开发可统计单词个数的Android驱动程序(1)
  2. 创建Android库的方法及Android(安卓).aar文件用法小结
  3. android中adb命令大全
  4. android adb shell 命令大全
  5. Android(安卓)adb shell 命令大全
  6. android aapt (android asset packaging tool)使用详解
  7. Android(安卓)adb shell 命令大全
  8. android的init.rc文件的语法
  9. android adb shell 命令大全

随机推荐

  1. Android(安卓)Phone进程启动过程
  2. Android(安卓)电话拨号
  3. Android中Service类onStartCommand的返回
  4. Android之列表对话框
  5. Android: Loading files from the Assets
  6. Android获取当前时间
  7. android 浮动按钮
  8. 日期和时间(DatePicker、TimePicker)
  9. 【特效】【自定义控件】关键字飘飞效果
  10. Android(安卓)10 获取相册图片失败