Eclipse下Andfix的使用

一: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);
		}
	}




你可能感兴趣的:(Android)