阿里Sophix热修复的简单集成和使用

时间:2024-04-11 07:24:15
快速上手Sophix 3.0.0
什么是热修复:指能够修复软件漏洞的一些代码,是一种快速、低成本修复产品软件版本缺陷的方式(百度)。说白就是当产品上线遇到bug,这个时候我们去发布一个新的版本,不但要过市场审核,而且发布没有多久又更新,对体检也不好。这个时候我们就要考虑到使用热修复了,在app启动的时候会去联网下载差分包然后进行修复。

1,到阿里注册账号,获取到appid,AppSecret,**
阿里Sophix热修复的简单集成和使用
2,Android studio 引入

maven {
    url "http://maven.aliyun.com/nexus/content/repositories/releases"
}

compile 'com.aliyun.ams:alicloud-android-hotfix:3.0.2'

3,初始化这个可以看官方文档 

public class MyApplication extends Application {
    private static MyApplication application;
    private static final String TAG = "MyApplication";
    @Override
    public void onCreate() {
        super.onCreate();
        application = this;
        init();
    }

    public static MyApplication newInstance() {
        return application;
    }

    private void init() {
        SophixManager.getInstance().setContext(this)
                .setAppVersion(getAppVersionName(this))
                .setAesKey(null)
                .setEnableDebug(true)
                .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                    @Override
                    public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
                        // 补丁加载回调通知
                        if (code == PatchStatus.CODE_LOAD_SUCCESS) {
                            // 表明补丁加载成功
                            Log.i(TAG, "onLoad: 成功");
                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                            // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启;
                            // 建议: 用户可以监听进入后台事件, 然后应用自杀
                            Log.i(TAG, "onLoad: 生效需要重启");
                            restartApp();
                        } else if (code == PatchStatus.CODE_LOAD_FAIL) {
                            // 内部引擎异常, 推荐此时清空本地补丁, 防止失败补丁重复加载
                            // SophixManager.getInstance().cleanPatches();
                        } else {
                            // 其它错误信息, 查看PatchStatus类说明
                            Log.i(TAG, "onLoad: 其它错误信息"+code);
                        }
                    }
                }).initialize();
        SophixManager.getInstance().queryAndLoadNewPatch();
    }


    /**
     * 返回当前程序版本名
     */
    public static String getAppVersionName(Context context) {
        String versionName = "";
        try {
            // ---get the package info---
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            versionName = pi.versionName;
            //versioncode = pi.versionCode;
            if (versionName == null || versionName.length() <= 0) {
                return "";
            }
        } catch (Exception e) {
            Log.e("VersionInfo", "Exception", e);
        }
        return versionName;
    }


    public void restartApp(){
        RestartAPPTool.restartAPP(this,2000);
    }
}

4,让app热修复以后进行重启,这步不是必须的,因为修复以后app下次启动的时候就修复好了,如果想马上生效可以让app进行重启。下面是重启APP代码。(阿里说可以安装热修复及时生效,好像我测试的代码不行,大家可以去挖掘,app重启毕竟下下选择)

public class killSelfService extends Service {

    private static  long stopDelayed=2000;
    private Handler handler;
    private String PackageName;
    public killSelfService() {
        handler=new Handler();
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {
        stopDelayed=intent.getLongExtra("Delayed",2000);
        PackageName=intent.getStringExtra("PackageName");
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage(PackageName);
                startActivity(LaunchIntent);
                killSelfService.this.stopSelf();
            }
        },stopDelayed);
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

注意服务最后在一个独立进程中进行,不要和app同一个进程,不然很容易被杀死。这个服务的逻辑是:启动一个app然后自杀(哈哈)。

public class RestartAPPTool {

    public static void restartAPP(Context context, long Delayed){


        Intent intent1=new Intent(context,killSelfService.class);
        intent1.putExtra("PackageName",context.getPackageName());
        intent1.putExtra("Delayed",Delayed);
        context.startService(intent1);
        android.os.Process.killProcess(android.os.Process.myPid());
    }
    public static void restartAPP(Context context){
        restartAPP(context,2000);
    }
}

app重启控制类,通知服务要重启的app,然后杀死自己(正在运行的app)。


public class MainActivity extends AppCompatActivity {

    private TextView tv;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //initView(); 这个是新的app添加的方法

    }

    private void initView() {
        tv = (TextView) findViewById(R.id.tv);
        tv.setText("我是热修复的app");
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "我是热修复的app", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

好这样就是一个app了,我们把他编译成一个apk文件。然后我们把initView();方法打开再编译一个apk文件作为一个新的app。

5,使用工具生成差分包上传到阿里后台。
阿里Sophix热修复的简单集成和使用

输出路径必填,其他按需。然后生成差分包,把sophix-patch.jar这个差分包上传到后台就行了。注意差分包名字是不能改的。
然后我们安装没有initView方法的apk包到模拟器,你会发现它运行后会重启成你新的apk了。
阿里Sophix热修复的简单集成和使用



注意什么样的情况下使用热修复:修复bug。上面的demo你运行会发现在一个old app已经存在的事件上进行修复是没有问题的,如果你在xml添加一个新的view的时候就会报错。代码动态添加没有测试过,所以热修复适合bug修复,逻辑更新不推荐使用。

好这样就简单上手了。具体热修复原理和使用可以看阿里文档。

demo下载:https://github.com/lcwooo/Application4