AndFix 阿里热修复Demo
一言不合先上代码。后面具体解释
Appliction 类
package com.mrko.basic;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import com.alipay.euler.andfix.patch.PatchManager;
import utils.MyException;
/**
* Author: Mrko
* Date: 2017/8/17
* Description:
*/
public class MyApplication extends Application {
public static PatchManager mPatchManager;
@Override
public void onCreate() {
super.onCreate();
MyException.getInstance().init(this);
initAndFix(this);
}
private void initAndFix(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
mPatchManager = new PatchManager(context);
mPatchManager.init(packageInfo.versionName);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
mPatchManager.loadPatch();
}
}
- AndFixActivity 类(有bug时)
package com.mrko.basic;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class AndFixActivity extends AppCompatActivity {
@BindView(R.id.creat_bug)
Button creatBug;
@BindView(R.id.fix_bug)
Button fixBug;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_and_fix);
ButterKnife.bind(this);
}
public void initAndFix() {
File file = new File(Environment.getExternalStorageDirectory(), "fix.apatch");
if (file.exists()) {
try {
MyApplication.mPatchManager.addPatch(file.getAbsolutePath());
Log.e("mrko", "热修复成功了");
Toast.makeText(this,"AndFix is success !",Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Log.e("mrko", "热修复失败了");
}
}
}
@OnClick({R.id.creat_bug, R.id.fix_bug})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.creat_bug:
Toast.makeText(this,"Creat bug !",Toast.LENGTH_LONG).show();
int i = 1 / 0;
Toast.makeText(this,"fix this bug ! i===1/2",Toast.LENGTH_LONG).show();
break;
case R.id.fix_bug:
Toast.makeText(this,"AndFix is Working !",Toast.LENGTH_LONG).show();
initAndFix();
break;
}
}
}
- AndFixActivity (修复bug之后)
package com.mrko.basic;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class AndFixActivity extends AppCompatActivity {
@BindView(R.id.creat_bug)
Button creatBug;
@BindView(R.id.fix_bug)
Button fixBug;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_and_fix);
ButterKnife.bind(this);
}
public void initAndFix() {
File file = new File(Environment.getExternalStorageDirectory(), "fix.apatch");
if (file.exists()) {
try {
MyApplication.mPatchManager.addPatch(file.getAbsolutePath());
Log.e("mrko", "热修复成功了");
Toast.makeText(this,"AndFix is success !",Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Log.e("mrko", "热修复失败了");
}
}
}
@OnClick({R.id.creat_bug, R.id.fix_bug})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.creat_bug:
Toast.makeText(this,"Creat bug !",Toast.LENGTH_LONG).show();
int i = 1 / 2;
Toast.makeText(this,"fix this bug ! i===1/2",Toast.LENGTH_LONG).show();
break;
case R.id.fix_bug:
Toast.makeText(this,"AndFix is Working !",Toast.LENGTH_LONG).show();
initAndFix();
break;
}
}
}
- 梳理思路:
a. 既然是阿里的AndFix的框架,必然少不了地址传送门;
b. 其实项目中已经说的很详细了。我就说下我实现的过程
c. 你需要在gradle中添加依赖 (版本号以阿里项目为基准)
dependencies {
compile 'com.alipay.euler:andfix:0.5.0@aar'
}
d. 需要在Application中实例化
patchManager = new PatchManager(context);
patchManager.init(appversion);//current version
patchManager.loadPatch();
e. 如果上两步实现了,代表你已经接入热修复框架了。
f. 那么问题来了、你原来的带bug的怎么修复呢、首先你原来带bug的项目一定是通过签名打出来的包。暂且定为old.apk。当你修复你的bug。然后重新签名打包。生成new.apk。
g. 这两个apk就是解决问题的关键。接下来我们需要到AndFix项目中下载tool-传送门
h. 解压到本地。然后将你签名文件xxx.jks、old.apk、new.apk、放在同一目录下、
i. 你需要打开cmd .将目录调到你的解压目录下。接下来你需要一个命令。
j. apkpatch.bat -f new.apk -t old.apk -o -out -k xxx.jks -p 你的密码 -a alias名称 -e alias密码
k. 这样会在本地成一个out文件夹。将后缀.apatch的文件名修改fix.apatch(自己随意,项目中使用)。
m. 最后 在修改的地方加上
patchManager.loadPatch();
类似于AndFixActivity的initAndFix()、这个越早加载越好、一般写在BaseActivity。
n. 然后将fix.apatch、文件复制到根目录、再去测试下、就发现bug修复好了。(一般这个是联网下载的。这作为demo就放在目录下、原理相同)
- 原理(粗鄙理解):
- 通过阿里的tools将两个apk的差异区分开。打出apatch文件。这个通过load之后会将原来的dex有差异的部分替换掉。、从而达到修复bug的目的、
- 深入探究可以去看源码怎么实现的、