Explorar el Código

[feat]键盘插件,Flutter端回调Android原生端,确保主线程回调

hezihao hace 9 meses
padre
commit
debaa44091
Se han modificado 12 ficheros con 153 adiciones y 29 borrados
  1. 23 4
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/KeyboardSelectComponent.kt
  2. 6 1
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/enums/FlutterMethod.kt
  3. 19 2
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/mvvm/repository/KeyboardRepository.kt
  4. 18 7
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/mvvm/viewmodel/KeyboardViewModel.kt
  5. 19 4
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/FlutterBridgeManager.kt
  6. 13 4
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/IBridgeApi.kt
  7. 1 1
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/CallResult.kt
  8. 1 1
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/CallResultList.kt
  9. 7 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/base/EmptyResp.kt
  10. 13 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/req/ChooseKeyboardReq.kt
  11. 2 2
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/KeyboardListModel.kt
  12. 31 3
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/util/FlutterMethodCaller.kt

+ 23 - 4
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/KeyboardSelectComponent.kt

@@ -60,10 +60,12 @@ class KeyboardSelectComponent @JvmOverloads constructor(
                 return@click
             }
             // 保存,用户选择的键盘
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateKeyboardType(selectKeyboard.name)
-            // 关闭选择器
-            hide()
+            chooseKeyboard(selectKeyboard, onSuccess = {
+                // 关闭选择器
+                hide()
+            }, onFail = {
+                ToastUtils.showShort(it)
+            })
         }
 
         // 配置列表
@@ -162,4 +164,21 @@ class KeyboardSelectComponent @JvmOverloads constructor(
             ToastUtils.showLong(it)
         }
     }
+
+    /**
+     * 选择键盘
+     */
+    private fun chooseKeyboard(
+        selectModel: KeyboardSelectModel,
+        onSuccess: () -> Unit,
+        onFail: (msg: String) -> Unit
+    ) {
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()?.chooseKeyboard(
+            selectModel,
+            onSuccess = {
+                onSuccess.invoke()
+            },
+            onFail = onFail
+        )
+    }
 }

+ 6 - 1
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/enums/FlutterMethod.kt

@@ -7,5 +7,10 @@ enum class FlutterMethod(val methodName: String) {
     /**
      * 获取键盘列表
      */
-    GET_KEYBOARD_LIST("getKeyboardList")
+    GET_KEYBOARD_LIST("getKeyboardList"),
+
+    /**
+     * 选择键盘
+     */
+    CHOOSE_KEY_BOARD("chooseKeyboard")
 }

+ 19 - 2
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/mvvm/repository/KeyboardRepository.kt

@@ -1,7 +1,9 @@
 package com.atmob.keyboard_android.mvvm.repository
 
 import com.atmob.keyboard_android.util.bridge.FlutterBridgeManager
-import com.atmob.keyboard_android.util.bridge.model.KeyboardListModel
+import com.atmob.keyboard_android.util.bridge.model.base.EmptyResp
+import com.atmob.keyboard_android.util.bridge.model.req.ChooseKeyboardReq
+import com.atmob.keyboard_android.util.bridge.model.resp.KeyboardListResp
 
 /**
  * 键盘Repository
@@ -11,9 +13,24 @@ class KeyboardRepository {
      * 获取键盘列表
      */
     fun getKeyboardList(
-        onSuccess: (resultObj: KeyboardListModel) -> Unit,
+        onSuccess: (resultObj: KeyboardListResp) -> Unit,
         onFail: (msg: String) -> Unit
     ) {
         FlutterBridgeManager.getKeyboardList(onSuccess, onFail)
     }
+
+    /**
+     * 选择键盘
+     */
+    fun chooseKeyboard(
+        keyboardId: String,
+        onSuccess: (resultObj: EmptyResp) -> Unit,
+        onFail: (msg: String) -> Unit
+    ) {
+        FlutterBridgeManager.chooseKeyboard(
+            req = ChooseKeyboardReq(keyboardId),
+            onSuccess,
+            onFail
+        )
+    }
 }

+ 18 - 7
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/mvvm/viewmodel/KeyboardViewModel.kt

@@ -10,6 +10,7 @@ import com.atmob.keyboard_android.enums.Tab
 import com.atmob.keyboard_android.model.KeyboardSelectModel
 import com.atmob.keyboard_android.mvvm.repository.KeyboardRepository
 import com.atmob.keyboard_android.util.ContextUtil
+import com.atmob.keyboard_android.util.bridge.model.base.EmptyResp
 
 /**
  * 键盘ViewModel
@@ -142,13 +143,6 @@ class KeyboardViewModel : ViewModel() {
     }
 
     /**
-     * 更新键盘类型
-     */
-    fun updateKeyboardType(keyboardType: String) {
-        _keyboardType.value = keyboardType
-    }
-
-    /**
      * 更新键盘的Tab
      */
     fun updateTab(tab: Tab) {
@@ -172,4 +166,21 @@ class KeyboardViewModel : ViewModel() {
             _keyboardList.value = it.keyboardInfos
         }, onFail)
     }
+
+    /**
+     * 选择键盘
+     *
+     * @param selectModel 键盘选择信息
+     */
+    fun chooseKeyboard(
+        selectModel: KeyboardSelectModel,
+        onSuccess: (resultObj: EmptyResp) -> Unit,
+        onFail: (msg: String) -> Unit
+    ) {
+        mKeyboardRepository.chooseKeyboard(selectModel.id, onSuccess = {
+            // 更新键盘类型
+            _keyboardType.value = selectModel.name
+            onSuccess.invoke(it)
+        }, onFail)
+    }
 }

+ 19 - 4
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/FlutterBridgeManager.kt

@@ -2,7 +2,9 @@ package com.atmob.keyboard_android.util.bridge
 
 import com.atmob.keyboard_android.constant.PluginConfig
 import com.atmob.keyboard_android.enums.FlutterMethod
-import com.atmob.keyboard_android.util.bridge.model.KeyboardListModel
+import com.atmob.keyboard_android.util.bridge.model.base.EmptyResp
+import com.atmob.keyboard_android.util.bridge.model.req.ChooseKeyboardReq
+import com.atmob.keyboard_android.util.bridge.model.resp.KeyboardListResp
 import com.atmob.keyboard_android.util.bridge.util.FlutterMethodCaller
 import com.atmob.keyboard_android.util.bridge.util.NativeMethodRegistry
 import io.flutter.embedding.engine.FlutterEngineCache
@@ -35,12 +37,25 @@ object FlutterBridgeManager : IBridgeApi {
     }
 
     override fun getKeyboardList(
-        onSuccess: (resultObj: KeyboardListModel) -> Unit,
+        onSuccess: (resultObj: KeyboardListResp) -> Unit,
         onFail: (msg: String) -> Unit
     ) {
-        mFlutterMethodCaller.callMethod<KeyboardListModel>(
+        mFlutterMethodCaller.callMethod<KeyboardListResp>(
             FlutterMethod.GET_KEYBOARD_LIST.methodName,
-            modelClazz = KeyboardListModel::class.java,
+            modelClazz = KeyboardListResp::class.java,
+            onSuccess = onSuccess,
+            onFail = onFail
+        )
+    }
+
+    override fun chooseKeyboard(
+        req: ChooseKeyboardReq,
+        onSuccess: (EmptyResp) -> Unit,
+        onFail: (String) -> Unit
+    ) {
+        mFlutterMethodCaller.callMethod<EmptyResp>(
+            FlutterMethod.CHOOSE_KEY_BOARD.methodName,
+            modelClazz = EmptyResp::class.java,
             onSuccess = onSuccess,
             onFail = onFail
         )

+ 13 - 4
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/IBridgeApi.kt

@@ -1,8 +1,8 @@
 package com.atmob.keyboard_android.util.bridge
 
-import com.atmob.keyboard_android.model.KeyboardSelectModel
-import com.atmob.keyboard_android.util.bridge.model.CallResult
-import com.atmob.keyboard_android.util.bridge.model.KeyboardListModel
+import com.atmob.keyboard_android.util.bridge.model.base.EmptyResp
+import com.atmob.keyboard_android.util.bridge.model.req.ChooseKeyboardReq
+import com.atmob.keyboard_android.util.bridge.model.resp.KeyboardListResp
 
 /**
  * 定义桥接交互API
@@ -17,7 +17,16 @@ interface IBridgeApi {
      * 获取键盘列表
      */
     fun getKeyboardList(
-        onSuccess: (resultObj: KeyboardListModel) -> Unit,
+        onSuccess: (resultObj: KeyboardListResp) -> Unit,
+        onFail: (msg: String) -> Unit
+    )
+
+    /**
+     * 选择键盘
+     */
+    fun chooseKeyboard(
+        req: ChooseKeyboardReq,
+        onSuccess: (resultObj: EmptyResp) -> Unit,
         onFail: (msg: String) -> Unit
     )
 }

+ 1 - 1
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/CallResult.kt

@@ -1,4 +1,4 @@
-package com.atmob.keyboard_android.util.bridge.model
+package com.atmob.keyboard_android.util.bridge.model.base
 
 import java.io.Serializable
 

+ 1 - 1
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/CallResultList.kt

@@ -1,4 +1,4 @@
-package com.atmob.keyboard_android.util.bridge.model
+package com.atmob.keyboard_android.util.bridge.model.base
 
 import java.io.Serializable
 

+ 7 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/base/EmptyResp.kt

@@ -0,0 +1,7 @@
+package com.atmob.keyboard_android.util.bridge.model.base
+
+/**
+ * 空的响应体
+ */
+class EmptyResp {
+}

+ 13 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/req/ChooseKeyboardReq.kt

@@ -0,0 +1,13 @@
+package com.atmob.keyboard_android.util.bridge.model.req
+
+import java.io.Serializable
+
+/**
+ * 选择键盘请求
+ */
+data class ChooseKeyboardReq(
+    /**
+     * 键盘Id
+     */
+    val keyboardId: String,
+) : Serializable

+ 2 - 2
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/model/KeyboardListModel.kt

@@ -1,4 +1,4 @@
-package com.atmob.keyboard_android.util.bridge.model
+package com.atmob.keyboard_android.util.bridge.model.resp
 
 import com.atmob.keyboard_android.model.KeyboardSelectModel
 import java.io.Serializable
@@ -6,6 +6,6 @@ import java.io.Serializable
 /**
  * 键盘列表模型
  */
-data class KeyboardListModel(
+data class KeyboardListResp(
     val keyboardInfos: List<KeyboardSelectModel>
 ) : Serializable

+ 31 - 3
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/util/FlutterMethodCaller.kt

@@ -1,5 +1,7 @@
 package com.atmob.keyboard_android.util.bridge.util
 
+import android.os.Handler
+import android.os.Looper
 import com.atmob.keyboard_android.constant.PluginConfig
 import com.atmob.keyboard_android.util.JsonUtil
 import io.flutter.embedding.engine.FlutterEngine
@@ -15,6 +17,11 @@ class FlutterMethodCaller {
     private lateinit var mMethodChannel: MethodChannel
 
     /**
+     * 主线程Handler,用于Flutter回调安卓端时,在主线程回调外部
+     */
+    private val mMainHandler = Handler(Looper.getMainLooper())
+
+    /**
      * 初始化
      */
     fun init(engine: FlutterEngine) {
@@ -37,16 +44,37 @@ class FlutterMethodCaller {
             override fun success(result: Any?) {
                 val resultJson = result.toString()
                 val resultObj = JsonUtil.parseJsonByClass<T>(resultJson, modelClazz)
-                onSuccess?.invoke(resultObj)
+                runOnUIThread {
+                    onSuccess?.invoke(resultObj)
+                }
             }
 
             override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
-                onFail?.invoke(errorMessage ?: "call error")
+                runOnUIThread {
+                    onFail?.invoke(errorMessage ?: "call error")
+                }
             }
 
             override fun notImplemented() {
-                onFail?.invoke("method not implemented")
+                runOnUIThread {
+                    onFail?.invoke("method not implemented")
+                }
             }
         })
     }
+
+    /**
+     * 在主线程运行回调
+     */
+    private fun runOnUIThread(callback: () -> Unit) {
+        // 如果已经在主线程了,直接回调
+        if (Looper.getMainLooper().thread == Thread.currentThread()) {
+            callback.invoke()
+        } else {
+            // 不在主线程,则切到主线程后,再回调
+            mMainHandler.post {
+                callback.invoke()
+            }
+        }
+    }
 }