一:Andfix是阿里巴巴的开源项目,可在在线修复一些小bug,但是限制比较多。这篇文章意在说明使用流程,不深入讨论利弊。
二:github上找到alibaba的andfix项目,下载,里面的tools文件夹里有打补丁工具,无需另外下载;
三:下载Andfix的library,CSDN下载频道就有,下载完成后,把自己的项目和library放入同一目录下!否则会添加失败;
四:在library的Properties->Android中勾选Is Library;在自己的项目中添加刚才的library;
五:本文实例只在本地进行,如果想从服务器加载补丁,可参考我的另一片文章()。
新建项目,新建Application,代码的作用注释也解释的比较清楚了;
public class AndFixApplication extends Application{
public static PatchManager mPatchManager;
@Override
public void onCreate() {
super.onCreate();
/*收集崩溃信息*/
// ExceptionCrashHandler.getInstance().init(this);
// 初始化patch管理类
mPatchManager = new PatchManager(this);
Log.e("application", "已经new过mPatchManager了");
// 初始化patch版本
mPatchManager.init("1.0");
// String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
// mPatchManager.init(appVersion);
// 加载已经添加到PatchManager中的patch
mPatchManager.loadPatch();
}
}
六:在MainActivity中,我做了一个textview,两个button,第一个button是加载补丁用的,第二个是加载bug用的,textview点击显示toast用于看出补丁的效果;
private TextView mTv;
private Button mBtn;
private Button mBtnError;
private static final String APATCH_PATH = "/fixEclipse.apatch"; // 补丁文件名
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mTv = (TextView) findViewById(R.id.tv1);
mTv.setText("点击此文本弹出提示");
// try {
// String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
// } catch (NameNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
mTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"修复前",Toast.LENGTH_LONG).show();
}
});
mBtn = (Button) findViewById(R.id.btn1);
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String patchFileStr = Environment.getExternalStorageDirectory().getAbsolutePath() + APATCH_PATH;
Log.e(TAG,"路径"+patchFileStr);
try {
AndFixApplication.mPatchManager.addPatch(patchFileStr);
Toast.makeText(MainActivity.this,"补丁加载成功",Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
});
//bug1
mBtnError = (Button) findViewById(R.id.btn2);
mBtnError.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int a = (Integer) null;
// int a = 1;
int c = a/1;
}
});
}
这是修复前的代码,接下来我们可以修改点击textview的toast中的内容,或者修改bug按钮下的代码(使a=1即可),使之不会崩溃(a为null时会出现空指针异常,程序崩溃);
七:在清单中,添加读写权限,以及application的name;
八:生成签名文件,生成方法可参考我的另一篇文章(),修改前的版本生成带签名的apk,修改后的版本生成带签名的apk;
九:使用我们开篇提到的打补丁工具:cmd进入tools文件夹,输入命令:apkpatch.bat -f AndfixDemo_2.apk -t AndfixDemo_1.apk -o test1 -k andfixKeystore -p 123456 -a andfixKeyAlias -e 123456
解释一下,上述参数从-f开始分别为:修改后的apk名称、修改前的apk名称、生成补丁的文件夹名称(就在tools目录下)、签名、签名密码、别名、别名密码。
回车,成功的话会出现有改动的方法名,失败的话也会出现错误提示;
然后把生成的补丁名字改为代码中的名字;放入sd卡主目录;
十:安装修改之前的apk,加载补丁,就是见证奇迹的时刻了。
十一:注意,如果需要连续加载补丁,必须修改library中PatchManager类下addPatch方法,改为
public void addPatch(String path) throws IOException {
File src = new File(path);
File dest = new File(mPatchDir, src.getName());
if(!src.exists()){
throw new FileNotFoundException(path);
}
if (dest.exists()) {
Log.d(TAG, "patch [" + path + "] has be loaded.");
// return;
boolean deleteResult = dest.delete();
if (deleteResult)
Log.e(TAG, "patch [" + dest.getPath() + "] has be delete.");
else {
Log.e(TAG, "patch [" + dest.getPath() + "] delete error");
return;
}
}
FileUtil.copyFile(src, dest);// copy to patch's directory
Patch patch = addPatch(dest);
if (patch != null) {
loadPatch(patch);
}
}