React Native Android(安卓)即时热更新bundle 以及增量更新bundle~
16lz
2021-01-26
本文仅仅提供热更新与热更新的思路
具体实现代码会提供一些核心代码。
1. 加载bundle
我加载bundle的方式不是放在RaactActivity中,而是实现ReactApplication,放在mainapplication,正常Android代码也会有一个application是程序启动的一些初始化工作。代码如下:
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override protected boolean getUseDeveloperSupport() { return com.HeMingNetwork.ruyipin.recruiter.BuildConfig.DEBUG; } @Override protected List getPackages() { return Arrays.asList( new MainReactPackage(), ); } @Nullable @Override protected String getJSBundleFile() { if (BuildConfig.DEBUG) { return super.getJSBundleFile(); } else { String path = MainApplication.this.getFilesDir().getAbsolutePath() + "/index.android.bundle"; if (!isFirstByMainActivity) { return super.getJSBundleFile(); } if (Utils.isFileExit(path)) { return MainApplication.this.getFilesDir().getAbsolutePath() + "/index.android.bundle"; } else { return super.getJSBundleFile(); } } } };
如果是debug,super.getJSBundleFile()跑的是本地磁盘上的bundle包,release模式下加载的是assets里的index.android.bundle。
属性isFirstByMainActivity判断是不是第一次使用,之后每次加载的都是下载在本地的bundle包,
2. 对比bundle
新建一个AppManager的管理bundle与apk的类,
@ReactMethod public void updateAppThods(ReadableMap readableMap) { Activity activity = getCurrentActivity(); SharedPreferences sp = activity.getSharedPreferences("latestVersion", 0); if (Integer.parseInt(sp.getString("bundelVersion", "1")) != Integer.parseInt(readableMap.getString("bundleVer"))) { NetHelper netHelper = new NetHelper(activity); netHelper.downJsBundle(); } else { Log.d("readableArray", "相等"); } }
updateAppThods是在js中调用的代码,js中有一个定时器定时读取bundle的版本接口,数据格式类似{bundleVer:”x”,bundleUrl:”url”,},如果版本号不同,就去下载bundle。
3. 下载bundle
public void downJsBundle(String urlStr) { final String fileName = "index.android.bundle"; final File dir = activity.getFilesDir(); File file = new File(dir, fileName); Log.d(TAG, file.getAbsolutePath()); if (file.exists()) { file.delete(); } OkHttpClient mOkHttpClient = new OkHttpClient(); Request request = new Request.Builder().url(urlStr).build(); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) {// Toast.makeText(activity,"bundle下载失败",Toast.LENGTH_SHORT).show(); Log.e("downJsBundle", "bundle下载失败"); activity.runOnUiThread(new Runnable() { @Override public void run() { new AlertDialog.Builder(activity).setTitle("网络错误") .setMessage("请检查网络连接") .setPositiveButton("确定", null).show(); } }); } @Override public void onResponse(Call call, Response response) throws IOException { InputStream inputStream = response.body().byteStream(); FileOutputStream fileOutputStream = null; try { File bundle = new File(dir, fileName); fileOutputStream = new FileOutputStream(bundle); byte[] buffer = new byte[2048]; int len = 0; double fileSize = 0; while ((len = inputStream.read(buffer)) != -1) { fileOutputStream.write(buffer, 0, len); fileSize += len; } Log.e("jsbundle", fileSize / 1024 / 1024 + "MB"); fileOutputStream.flush(); Log.e("downJsBundle", "bundle下载成功"); Log.d("downJsBundle", "bundleVersion==" + bundleVersion); VersionMgr.bundelVersion = bundleVersion; SharedPreferences sp = activity.getSharedPreferences("latestVersion", 0); SharedPreferences.Editor edit = sp.edit(); edit.putString("bundelVersion", bundleVersion); edit.commit(); edit.putString("bundelVersion", VersionMgr.bundelVersion); activity.runOnUiThread(new Runnable() { @Override public void run() { new AlertDialog.Builder(activity).setTitle("有新版本的更新") .setMessage("需要更新嘛?") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { activity.runOnUiThread(new Runnable() { @Override public void run() { Intent intent = activity.getBaseContext().getPackageManager().getLaunchIntentForPackage(activity.getBaseContext().getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); activity.startActivity(intent); activity.finish(); } }); } }) .setNegativeButton("取消", null) .show(); } }); } catch (IOException e) { Log.e("downJsBundle", "bundle保存失败" + e.toString()); e.printStackTrace(); }// activity.runOnUiThread(new Runnable() {// @Override// public void run() {// activity.startActivity(new Intent(activity, MainActivity.class));// activity.finish();// }// }); } }); }
bundle 并且把版本号存在本地。
4 增量更新
待续~~
更多相关文章
- Android中使用DownloadManager下载并安装apk
- android 反编译心得
- android GridView 长按事件不管用
- windows xp 搭建(配置)android开发环境(一)
- Android一些开发小技巧_不定期更新
- 如何从C++代码直接访问android framework层的WifiService
- android基于NDK的环境搭建――上
- 使用Handler在子线程中更新UI
- android studio 快捷键(本文持续更新)