一:Andfix是阿里巴巴的开源项目,可在在线修复一些小bug,但是限制比较多。这篇文章意在说明使用流程,不深入讨论利弊。
二:github上找到alibaba的andfix项目,下载,里面的tools文件夹里有打补丁工具,无需另外下载;
三:下载Andfix的library,下载频道就有,下载完成后,把自己的项目和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); } }