feat(bundle): 优化 bundle 更新逻辑
- 添加 BundleUpdateEvent 用于通知 bundle 更新完成 - 修改 MainApplication 中的 bundle 更新逻辑,支持增量更新 - 新增 WelcomeActivity 作为启动页,处理 bundle 更新和跳转逻辑 - 更新布局文件和 AndroidManifest.xml 以适应新的启动流程 - 添加 eventbus 依赖用于事件通知
这个提交包含在:
父节点
92d2fb20fe
当前提交
ff2252715c
@ -110,6 +110,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// The version of react-native is set by the React Native Gradle Plugin
|
// The version of react-native is set by the React Native Gradle Plugin
|
||||||
implementation("com.facebook.react:react-android")
|
implementation("com.facebook.react:react-android")
|
||||||
|
implementation("org.greenrobot:eventbus:3.3.1")
|
||||||
|
|
||||||
if (hermesEnabled.toBoolean()) {
|
if (hermesEnabled.toBoolean()) {
|
||||||
implementation("com.facebook.react:hermes-android")
|
implementation("com.facebook.react:hermes-android")
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".WelcomeActivity"
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
@ -23,6 +23,7 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity android:name="com.trust.ywx.MainActivity" />
|
||||||
<activity android:name="com.trust.ywx.BuzActivity" />
|
<activity android:name="com.trust.ywx.BuzActivity" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
二进制文件未显示。
二进制文件未显示。
@ -32,8 +32,6 @@ class BuzActivity : ReactActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
AppManager.addActivity(this)
|
AppManager.addActivity(this)
|
||||||
Toast.makeText(this, "BuzActivity:" + NavigationHelper.routerName, Toast.LENGTH_SHORT)
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
|||||||
@ -9,8 +9,12 @@ import com.facebook.react.ReactNativeHost
|
|||||||
import com.facebook.react.ReactPackage
|
import com.facebook.react.ReactPackage
|
||||||
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
||||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||||
|
import com.trust.ywx.event.BundleUpdateEvent
|
||||||
import com.trust.ywx.specs.navigation.NavigationPackage
|
import com.trust.ywx.specs.navigation.NavigationPackage
|
||||||
|
import com.trust.ywx.utils.BUNDLE_VERSION_CODE
|
||||||
import com.trust.ywx.utils.FileHelper
|
import com.trust.ywx.utils.FileHelper
|
||||||
|
import com.trust.ywx.utils.SHARED_PREFERENCES_NAME
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class MainApplication : Application(), ReactApplication {
|
class MainApplication : Application(), ReactApplication {
|
||||||
@ -30,7 +34,7 @@ class MainApplication : Application(), ReactApplication {
|
|||||||
override fun getJSBundleFile(): String? = if (getUseDeveloperSupport()) {
|
override fun getJSBundleFile(): String? = if (getUseDeveloperSupport()) {
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
FileHelper.getFilePath("common.android.bundle", this@MainApplication, "bundles")
|
FileHelper.getFilePath("common.android.bundle", this@MainApplication, "bundles/android")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
|
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
|
||||||
@ -43,23 +47,46 @@ class MainApplication : Application(), ReactApplication {
|
|||||||
get() = getDefaultReactHost(applicationContext, reactNativeHost)
|
get() = getDefaultReactHost(applicationContext, reactNativeHost)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var isNew = true
|
var isInit = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
val f = File(FileHelper.getDirPath(this, "bundles"))
|
|
||||||
val bf = File(FileHelper.getFilePath("bundle.zip", this, "bundles"))
|
|
||||||
if (!f.exists() || !f.isDirectory) {
|
|
||||||
f.mkdirs()
|
|
||||||
}
|
|
||||||
if (f.list().size <= 1) {
|
|
||||||
bf.delete()
|
|
||||||
FileHelper.copyAssetFileToInternalStorage(this, "bundle.zip", bf)
|
|
||||||
if (bf.exists()) {
|
|
||||||
FileHelper.unzip(bf, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
if (!BuildConfig.DEBUG)
|
||||||
|
createOrUpdateBundle()
|
||||||
loadReactNative(this)
|
loadReactNative(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createOrUpdateBundle() {
|
||||||
|
// 使用中的bundle版本
|
||||||
|
val sharedPref = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE)
|
||||||
|
val bundleVersion = sharedPref.getInt("bundle_version", 0)
|
||||||
|
|
||||||
|
// apk携带的bundle版本
|
||||||
|
val localBundleVersion = BUNDLE_VERSION_CODE
|
||||||
|
// 本地bundle目录
|
||||||
|
val f = File(FileHelper.getDirPath(this, "bundles"))
|
||||||
|
|
||||||
|
// 使用中的bundle比apk携带的小,则直接复制解压
|
||||||
|
if (bundleVersion < localBundleVersion || !f.exists() || !f.isDirectory) {
|
||||||
|
// bundle.zip在本地的路径
|
||||||
|
val bf = File(FileHelper.getFilePath("bundle.zip", this, "bundles"))
|
||||||
|
// 果断点,直接删除重建
|
||||||
|
if (f.exists() && !f.isDirectory) {
|
||||||
|
f.delete()
|
||||||
|
}
|
||||||
|
f.mkdirs()
|
||||||
|
// 拷贝bundle.zip
|
||||||
|
FileHelper.copyAssetFileToInternalStorage(this, "android.zip", bf)
|
||||||
|
if (bf.exists()) {
|
||||||
|
// 复制成功后,直接解压
|
||||||
|
FileHelper.unzip(bf, f)
|
||||||
|
isInit = true
|
||||||
|
EventBus.getDefault().post(BundleUpdateEvent())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isInit = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,51 @@
|
|||||||
|
package com.trust.ywx
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.trust.ywx.event.BundleUpdateEvent
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.greenrobot.eventbus.Subscribe
|
||||||
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
|
||||||
|
|
||||||
|
class WelcomeActivity : AppCompatActivity() {
|
||||||
|
val handler = Handler(Looper.getMainLooper())
|
||||||
|
val runnable = Runnable {
|
||||||
|
if (MainApplication.isInit) {
|
||||||
|
startActivity(Intent(this@WelcomeActivity, MainActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
AppManager.addActivity(this)
|
||||||
|
handler.postDelayed(runnable, 3000)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onMessageEvent(event: BundleUpdateEvent) {
|
||||||
|
handler.removeCallbacks(runnable)
|
||||||
|
startActivity(Intent(this@WelcomeActivity, MainActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
EventBus.getDefault().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
EventBus.getDefault().unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
AppManager.removeActivity(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
package com.trust.ywx.event;
|
||||||
|
|
||||||
|
public class BundleUpdateEvent {
|
||||||
|
}
|
||||||
@ -52,9 +52,9 @@ class MultipleReactActivityDelegate(
|
|||||||
helper.loadBundle(
|
helper.loadBundle(
|
||||||
JSBundleLoader.createFileLoader(
|
JSBundleLoader.createFileLoader(
|
||||||
FileHelper.getFilePath(
|
FileHelper.getFilePath(
|
||||||
"$mainComponentName.android.bundle",
|
"buz.android.bundle",
|
||||||
this.reactActivity.applicationContext,
|
this.reactActivity.applicationContext,
|
||||||
"bundles"
|
"bundles/android"
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -91,7 +91,7 @@ class MultipleReactActivityDelegate(
|
|||||||
val fileName = FileHelper.getFilePath(
|
val fileName = FileHelper.getFilePath(
|
||||||
"$mainComponentName.android.bundle",
|
"$mainComponentName.android.bundle",
|
||||||
reactActivity.applicationContext,
|
reactActivity.applicationContext,
|
||||||
"bundles"
|
"bundles/android"
|
||||||
)
|
)
|
||||||
instance?.loadScriptFromFile(
|
instance?.loadScriptFromFile(
|
||||||
fileName,
|
fileName,
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.trust.ywx.utils
|
||||||
|
|
||||||
|
// 每次发版得改一下这里,保证bundle是最新的
|
||||||
|
const val BUNDLE_VERSION_CODE = 1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以下为常量,不需要修改
|
||||||
|
*/
|
||||||
|
const val SHARED_PREFERENCES_NAME = "com.trust.ywx.PREFERENCE_FILE_KEY"
|
||||||
@ -1,18 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:gravity="center"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:gravity="center">
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
<TextView
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:text="button1"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/btn1"
|
android:text="欢迎使用"
|
||||||
android:layout_gravity="center"/>
|
android:textSize="33sp" />
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="button2"
|
|
||||||
android:id="@+id/btn2"
|
|
||||||
android:layout_gravity="center"/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
文件差异因一行或多行过长而隐藏
@ -0,0 +1,7 @@
|
|||||||
|
__d(function(g,r,i,a,m,e,d){r(d[0]),r(d[1])},10000000,[10000001,10000003]);
|
||||||
|
__d(function(g,r,i,a,m,e,d){var n=r(d[0]),t=r(d[1]),p=n(r(d[2]));t.AppRegistry.registerComponent(r(d[3]).Apps.Ywq,function(){return p.default})},10000001,[1,2,10000002,492]);
|
||||||
|
__d(function(g,r,i,a,m,e,d){var t=r(d[0]);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var n=r(d[1]),o=t(r(d[2])),s=r(d[3]);var l=n.StyleSheet.create({container:{flex:1}});e.default=function(){var t='dark'===(0,n.useColorScheme)();return(0,s.jsxs)(n.View,{style:l.container,children:[(0,s.jsx)(n.StatusBar,{barStyle:t?'light-content':'dark-content'}),(0,s.jsx)(n.View,{style:{height:100}}),(0,s.jsx)(n.Button,{title:'onConfirm',onPress:function(){}}),(0,s.jsx)(n.View,{style:{height:15}}),(0,s.jsx)(n.Button,{title:'Toast',onPress:function(){(0,r(d[4]).showMessage)('\u533b\u7f51\u7b7e\u5f39\u51fatoast-error','error')}}),(0,s.jsx)(o.default,{})]})}},10000002,[1,2,511,243,538]);
|
||||||
|
__d(function(g,r,i,a,m,e,d){var t=r(d[0]),n=r(d[1]),p=t(r(d[2]));n.AppRegistry.registerComponent(r(d[3]).Apps.Hospital,function(){return p.default})},10000003,[1,2,10000004,492]);
|
||||||
|
__d(function(g,r,i,a,m,e,d){var t=r(d[0]);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var n=r(d[1]),o=t(r(d[2])),s=r(d[3]);var l=n.StyleSheet.create({container:{flex:1}});e.default=function(){var t='dark'===(0,n.useColorScheme)();return(0,s.jsxs)(n.View,{style:l.container,children:[(0,s.jsx)(n.StatusBar,{barStyle:t?'light-content':'dark-content'}),(0,s.jsx)(n.View,{style:{height:100}}),(0,s.jsx)(n.Text,{children:"\u4e92\u8054\u7f51\u533b\u9662"}),(0,s.jsx)(n.Button,{title:'\u8fd4\u56de',onPress:function(){(0,r(d[4]).pop)()}}),(0,s.jsx)(n.View,{style:{height:15}}),(0,s.jsx)(n.Button,{title:'Toast',onPress:function(){(0,r(d[5]).showMessage)('\u4e92\u8054\u7f51\u533b\u9662\u5f39\u51fatoast','info','common\u5411\u4e0b\u517c\u5bb9')}}),(0,s.jsx)(o.default,{})]})}},10000004,[1,2,511,243,492,538]);
|
||||||
|
__r(108);
|
||||||
|
__r(10000000);
|
||||||
@ -1,4 +0,0 @@
|
|||||||
__d(function(g,r,i,a,m,e,d){var t=r(d[0]),n=r(d[1]),p=t(r(d[2]));n.AppRegistry.registerComponent(r(d[3]).Apps.Hospital,function(){return p.default})},10000000,[5,3,10000001,491]);
|
|
||||||
__d(function(g,r,i,a,m,e,d){var t=r(d[0]);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var n=r(d[1]),o=t(r(d[2])),s=r(d[3]);var l=n.StyleSheet.create({container:{flex:1}});e.default=function(){var t='dark'===(0,n.useColorScheme)();return(0,s.jsxs)(n.View,{style:l.container,children:[(0,s.jsx)(n.StatusBar,{barStyle:t?'light-content':'dark-content'}),(0,s.jsx)(n.View,{style:{height:100}}),(0,s.jsx)(n.Text,{children:"\u4e92\u8054\u7f51\u533b\u9662"}),(0,s.jsx)(n.Button,{title:'\u8fd4\u56de',onPress:function(){(0,r(d[4]).pop)()}}),(0,s.jsx)(n.View,{style:{height:15}}),(0,s.jsx)(n.Button,{title:'Toast',onPress:function(){(0,r(d[5]).showMessage)('\u4e92\u8054\u7f51\u533b\u9662\u5f39\u51fatoast','info','common\u5411\u4e0b\u517c\u5bb9')}}),(0,s.jsx)(o.default,{})]})}},10000001,[5,3,503,243,491,502]);
|
|
||||||
__r(108);
|
|
||||||
__r(10000000);
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
__d(function(g,r,i,a,m,e,d){var n=r(d[0]),t=r(d[1]),p=n(r(d[2]));t.AppRegistry.registerComponent(r(d[3]).Apps.Ywq,function(){return p.default})},10000000,[1,2,10000001,492]);
|
|
||||||
__d(function(g,r,i,a,m,e,d){var t=r(d[0]);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var n=r(d[1]),o=t(r(d[2])),s=r(d[3]);var l=n.StyleSheet.create({container:{flex:1}});e.default=function(){var t='dark'===(0,n.useColorScheme)();return(0,s.jsxs)(n.View,{style:l.container,children:[(0,s.jsx)(n.StatusBar,{barStyle:t?'light-content':'dark-content'}),(0,s.jsx)(n.View,{style:{height:100}}),(0,s.jsx)(n.Button,{title:'onConfirm',onPress:function(){}}),(0,s.jsx)(n.View,{style:{height:15}}),(0,s.jsx)(n.Button,{title:'Toast',onPress:function(){(0,r(d[4]).showMessage)('\u533b\u7f51\u7b7e\u5f39\u51fatoast-error','error')}}),(0,s.jsx)(o.default,{})]})}},10000001,[1,2,511,243,538]);
|
|
||||||
__r(108);
|
|
||||||
__r(10000000);
|
|
||||||
@ -10,6 +10,7 @@
|
|||||||
"start": "react-native start",
|
"start": "react-native start",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"build-android-common": "react-native bundle --platform android --dev false --entry-file src/app/app.ts --bundle-output bundle/android/common.android.bundle --assets-dest ./bundle/android --config metro.common.config.js --minify true --reset-cache",
|
"build-android-common": "react-native bundle --platform android --dev false --entry-file src/app/app.ts --bundle-output bundle/android/common.android.bundle --assets-dest ./bundle/android --config metro.common.config.js --minify true --reset-cache",
|
||||||
|
"build-android-buz": "react-native bundle --platform android --dev false --entry-file src/buz.ts --bundle-output ./bundle/android/buz.android.bundle --assets-dest ./bundle/android --config metro.main.config.js --minify true --reset-cache",
|
||||||
"build-android-ywq": "react-native bundle --platform android --dev false --entry-file src/ywq/ywq.ts --bundle-output ./bundle/android/ywq.android.bundle --assets-dest ./bundle/android --config metro.main.config.js --minify true --reset-cache",
|
"build-android-ywq": "react-native bundle --platform android --dev false --entry-file src/ywq/ywq.ts --bundle-output ./bundle/android/ywq.android.bundle --assets-dest ./bundle/android --config metro.main.config.js --minify true --reset-cache",
|
||||||
"build-android-hospital": "react-native bundle --platform android --dev false --entry-file src/hospital/hospital.ts --bundle-output bundle/android/hospital.android.bundle --assets-dest ./bundle/android --config metro.main.config.js --minify true --reset-cache",
|
"build-android-hospital": "react-native bundle --platform android --dev false --entry-file src/hospital/hospital.ts --bundle-output bundle/android/hospital.android.bundle --assets-dest ./bundle/android --config metro.main.config.js --minify true --reset-cache",
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"app": {
|
|
||||||
"name": "app"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2
src/buz.ts
普通文件
2
src/buz.ts
普通文件
@ -0,0 +1,2 @@
|
|||||||
|
import '@ywx/ywq.ts';
|
||||||
|
import '@hospital/hospital.ts';
|
||||||
正在加载...
在新工单中引用
屏蔽一个用户