本文仅仅提供热更新与热更新的思路
具体实现代码会提供一些核心代码。
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<ReactPackage> getPackages() {
return Arrays.<ReactPackage>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 增量更新 待续~~