Преглед на файлове

feat(bundle): 优化 bundle 更新逻辑

- 添加 BundleUpdateEvent 用于通知 bundle 更新完成
- 修改 MainApplication 中的 bundle 更新逻辑,支持增量更新
- 新增 WelcomeActivity 作为启动页,处理 bundle 更新和跳转逻辑
- 更新布局文件和 AndroidManifest.xml 以适应新的启动流程
- 添加 eventbus 依赖用于事件通知
xuqm преди 1 седмица
родител
ревизия
ff2252715c

+ 1 - 0
android/app/build.gradle

@@ -110,6 +110,7 @@ android {
 dependencies {
     // The version of react-native is set by the React Native Gradle Plugin
     implementation("com.facebook.react:react-android")
+    implementation("org.greenrobot:eventbus:3.3.1")
 
     if (hermesEnabled.toBoolean()) {
         implementation("com.facebook.react:hermes-android")

+ 2 - 1
android/app/src/main/AndroidManifest.xml

@@ -12,7 +12,7 @@
         android:supportsRtl="true"
         android:theme="@style/AppTheme">
         <activity
-            android:name=".MainActivity"
+            android:name=".WelcomeActivity"
             android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
             android:exported="true"
             android:label="@string/app_name"
@@ -23,6 +23,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name="com.trust.ywx.MainActivity" />
         <activity android:name="com.trust.ywx.BuzActivity" />
     </application>
 </manifest>

BIN
android/app/src/main/assets/android.zip


BIN
android/app/src/main/assets/bundle.zip


+ 0 - 2
android/app/src/main/java/com/trust/ywx/BuzActivity.kt

@@ -32,8 +32,6 @@ class BuzActivity : ReactActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         AppManager.addActivity(this)
-        Toast.makeText(this, "BuzActivity:" + NavigationHelper.routerName, Toast.LENGTH_SHORT)
-            .show()
     }
 
     override fun onResume() {

+ 37 - 10
android/app/src/main/java/com/trust/ywx/MainApplication.kt

@@ -9,8 +9,12 @@ import com.facebook.react.ReactNativeHost
 import com.facebook.react.ReactPackage
 import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
 import com.facebook.react.defaults.DefaultReactNativeHost
+import com.trust.ywx.event.BundleUpdateEvent
 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.SHARED_PREFERENCES_NAME
+import org.greenrobot.eventbus.EventBus
 import java.io.File
 
 class MainApplication : Application(), ReactApplication {
@@ -30,7 +34,7 @@ class MainApplication : Application(), ReactApplication {
         override fun getJSBundleFile(): String? = if (getUseDeveloperSupport()) {
             null
         } else {
-            FileHelper.getFilePath("common.android.bundle", this@MainApplication, "bundles")
+            FileHelper.getFilePath("common.android.bundle", this@MainApplication, "bundles/android")
         }
 
         override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
@@ -43,23 +47,46 @@ class MainApplication : Application(), ReactApplication {
         get() = getDefaultReactHost(applicationContext, reactNativeHost)
 
     companion object {
-        var isNew = true
+        var isInit = false
     }
 
     override fun onCreate() {
+        super.onCreate()
+        if (!BuildConfig.DEBUG)
+            createOrUpdateBundle()
+        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"))
-        val bf = File(FileHelper.getFilePath("bundle.zip", this, "bundles"))
-        if (!f.exists() || !f.isDirectory) {
+
+        // 使用中的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()
-        }
-        if (f.list().size <= 1) {
-            bf.delete()
-            FileHelper.copyAssetFileToInternalStorage(this, "bundle.zip", bf)
+            // 拷贝bundle.zip
+            FileHelper.copyAssetFileToInternalStorage(this, "android.zip", bf)
             if (bf.exists()) {
+                // 复制成功后,直接解压
                 FileHelper.unzip(bf, f)
+                isInit = true
+                EventBus.getDefault().post(BundleUpdateEvent())
             }
+        } else {
+            isInit = true
         }
-        super.onCreate()
-        loadReactNative(this)
+
     }
 }

+ 51 - 0
android/app/src/main/java/com/trust/ywx/WelcomeActivity.kt

@@ -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)
+    }
+}

+ 4 - 0
android/app/src/main/java/com/trust/ywx/event/BundleUpdateEvent.java

@@ -0,0 +1,4 @@
+package com.trust.ywx.event;
+
+public class BundleUpdateEvent {
+}

+ 3 - 3
android/app/src/main/java/com/trust/ywx/multiple/MultipleReactActivityDelegate.kt

@@ -52,9 +52,9 @@ class MultipleReactActivityDelegate(
                 helper.loadBundle(
                     JSBundleLoader.createFileLoader(
                         FileHelper.getFilePath(
-                            "$mainComponentName.android.bundle",
+                            "buz.android.bundle",
                             this.reactActivity.applicationContext,
-                            "bundles"
+                            "bundles/android"
                         )
                     ),
                 )
@@ -91,7 +91,7 @@ class MultipleReactActivityDelegate(
                         val fileName = FileHelper.getFilePath(
                             "$mainComponentName.android.bundle",
                             reactActivity.applicationContext,
-                            "bundles"
+                            "bundles/android"
                         )
                         instance?.loadScriptFromFile(
                             fileName,

+ 10 - 0
android/app/src/main/java/com/trust/ywx/utils/VersionHelper.kt

@@ -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"

+ 8 - 14
android/app/src/main/res/layout/activity_main.xml

@@ -1,18 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:gravity="center"
-    android:layout_height="match_parent">
-<Button
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:text="button1"
-    android:id="@+id/btn1"
-    android:layout_gravity="center"/>
-<Button
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:text="button2"
-    android:id="@+id/btn2"
-    android:layout_gravity="center"/>
+    android:layout_height="match_parent"
+    android:gravity="center">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="欢迎使用"
+        android:textSize="33sp" />
 </LinearLayout>

Файловите разлики са ограничени, защото са твърде много
+ 0 - 2
bundle/android/app.android.bundle


+ 7 - 0
bundle/android/buz.android.bundle

@@ -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);

+ 0 - 4
bundle/android/hospital.android.bundle

@@ -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);

+ 0 - 4
bundle/android/ywq.android.bundle

@@ -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);

+ 1 - 0
package.json

@@ -10,6 +10,7 @@
     "start": "react-native start",
     "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-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-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",
 

+ 0 - 5
src/app.json

@@ -1,5 +0,0 @@
-{
-  "app": {
-    "name": "app"
-  }
-}

+ 2 - 0
src/buz.ts

@@ -0,0 +1,2 @@
+import '@ywx/ywq.ts';
+import '@hospital/hospital.ts';

Някои файлове не бяха показани, защото твърде много файлове са промени