国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Flutter 與第三方 Native-SDK 的交互代理方案

這篇具有很好參考價值的文章主要介紹了Flutter 與第三方 Native-SDK 的交互代理方案。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

場景

在使用 Flutter 進行功能模塊或者整體項目的開發(fā)時,如果需要(階段性)頻繁地和某個第三方 Native-SDK 進行交互,而該 Native-SDK 沒有實現(xiàn) Flutter 插件版本的情況下,如果直接把這部分交互 API 加入到原有的 channel 類里面,會使得該 channel 類變得臃腫,造成代碼維護及迭代上的難度;而且,對于一些平常比較少用到的功能,也不需要一上來就初始化 channel-api,占用空間,而是在使用時才初始化,使用后也可以手動清除;

在此提出一種“Flutter 與第三方 Native-SDK 的交互代理方案”,通過一種“代理包裝”的方式,嘗試較好地解決以上提到的問題;

效果

該方案使用的是 Flutter+Android 進行 demo,全屏 loading、底部灰底 toast 為 Android 端實現(xiàn),方塊 loading、中間黑底 toast 為 Flutter 端實現(xiàn)

Flutter 與第三方 Native-SDK 的交互代理方案

范例

需要使用時才開啟 channel,使用結(jié)束后關(guān)閉 channel 監(jiān)聽

class _TestPageState extends State<TestPage> {
  
  void initState() {
    super.initState();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Channel')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            GestureDetector(
              onTap: () => channelTest(),
              child: const Text('開啟通道,進行交互'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> channelTest() async {
    TestChannelProxy? channel = await TestChannelProxy.openChannel();
    if (channel != null) {
      Function()? cancel;
      channel.doSomethingAndListener(DoSomethingCallback(
        onTestFirst: (result) {
          cancel = MsgUtil.loading(msg: result);
        },
        onTestSecond: () {
          cancel?.call();
        },
        onTestThird: (result) async {
          MsgUtil.toast(result.toString());
          return !result;
        },
      ));
    }
  }
}

代碼(Flutter 端代理類)

維護與 Native 端的交互,使用者不需要知道具體交互邏輯,但是在該代理類中,需要保證每次有回調(diào)的交互都能正確回調(diào)(不管是狀態(tài)為成功的回調(diào),還是狀態(tài)為失敗的回調(diào))

import 'package:flutter/services.dart';

import 'platform_method_channel.dart';

const String _testChannelName = 'zzq.channel.TestChannelProxy';

class TestChannelProxy {
  late MethodChannel _channel;
  DoSomethingCallback? _callback;

  TestChannelProxy._() {
    _channel = const MethodChannel(_testChannelName);
    _channel.setMethodCallHandler(_handleMethod);
  }

  /// [return] 為空表示開啟失敗,不為空表示開啟成功
  static Future<TestChannelProxy?> openChannel() async {
    bool success = await PlatformMethodChannel.getInstance()
        .openPlatformChannel(_testChannelName);
    return success ? TestChannelProxy._() : null;
  }
  
  /*Future<void> closeChannel() async {
    await _channel.invokeMethod('closeChannel');
    _channel.setMethodCallHandler(null);
  }*/

  // ------------------------------ flutter 調(diào)用 native ------------------------------

  void doSomethingAndListener(DoSomethingCallback callback) {
    _callback = callback;
    _channel.invokeMethod('doSomethingAndListener');
  }

  // ------------------------------ native 調(diào)用 flutter ------------------------------

  Future _handleMethod(MethodCall call) async {
    var args = call.arguments;
    switch (call.method) {
      case 'getString':
        return _getString();
      case 'getBoolean':
        return _getBoolean();
      case 'onTestFirst':
        _onTestFirst(args);
        break;
      case 'onTestSecond':
        _onTestSecond();
        break;
      case 'onTestThird':
        return _onTestThird(args);
      default:
        break;
    }
  }

  Future<String> _getString() async {
    await Future.delayed(const Duration(seconds: 2));
    return 'String';
  }

  Future<bool> _getBoolean() async {
    await Future.delayed(const Duration(seconds: 2));
    return true;
  }

  void _onTestFirst(String result) {
    _callback?.onTestFirst?.call(result);
  }

  void _onTestSecond() {
    _callback?.onTestSecond?.call();
  }

  Future<bool> _onTestThird(bool result) async {
    return (await _callback?.onTestThird?.call(result)) ?? false;
  }
}

class DoSomethingCallback {
  final Function(String result)? onTestFirst;
  final Function()? onTestSecond;
  final Future<bool> Function(bool result)? onTestThird;

  DoSomethingCallback({
    this.onTestFirst,
    this.onTestSecond,
    this.onTestThird,
  });
}

需要在默認/全局的 channel 中定義通用的開啟 channel 的 api,提供代理交互 channel 的開啟能力

  /// 開啟 flutter 與 native 端的交互通道,用于使用第三方 native-sdk 的能力
  /// 可以是 BasicMessageChannel、MethodChannel、EventChannel
  /// [return] 通道是否開啟成功
  Future<bool> openPlatformChannel(String channelName) async {
    var result = await _channel.invokeMethod('openPlatformChannel', channelName);
    return result == true;
  }
    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        val args = call.arguments
        when (call.method) {
            "openPlatformChannel" -> openPlatformChannel(args as String, result)
            else -> result.notImplemented()
        }
    }

    /**
     * 開啟 flutter 與 native 端的交互通道,用于 flutter 端使用第三方 native-sdk 的能力
     * 可以是 BasicMessageChannel、MethodChannel、EventChannel
     * [result.success] 通道是否開啟成功
     */
    private fun openPlatformChannel(channelName: String, result: MethodChannel.Result) {
        var success = true
        when (channelName) {
            TEST_CHANNEL_NAME -> TestTool.openChannel(binaryMessenger)
            else -> success = false
        }
        result.success(success)
    }

代碼(Android 端第三方 Native-SDK 包裝類)

該類用于包裝第三方 Native-SDK 所提供的能力,同時持有、維護 Flutter-Android-channel 中在 Android 端的代理 channel 實例;即該類負責(zé) SDK 能力使用及拓展,而 channel 代理類只負責(zé)通訊(發(fā)起及監(jiān)聽等)

import io.flutter.plugin.common.BinaryMessenger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

object TestTool {

    private var testChannelProxy: TestChannelProxy? = null

    fun openChannel(messenger: BinaryMessenger) {
        if (testChannelProxy == null) {
            synchronized(TestTool::class.java) {
                if (testChannelProxy == null) {
                    testChannelProxy = TestChannelProxy(messenger)
                }
            }
        }
    }
    
    /*fun closeChannel() {
        testChannelProxy = null
    }*/

    fun doSomethingAndListener() {
        DialogManager.showLoading()
        testChannelProxy?.getBoolean { it ->
            DialogManager.hideLoading()
            if (it) {
                CoroutineScope(Dispatchers.Main).launch {
                    delay(2000)
                    testChannelProxy?.onTestFirst("點了")
                    delay(2000)
                    testChannelProxy?.onTestSecond()
                    delay(2000)
                    testChannelProxy?.onTestThird(true) {
                        DialogManager.toast(it.toString())
                    }
                }
            }
        }
    }

}

代碼(Android 端代理類)

維護與 Flutter 端的交互,使用者不需要知道具體交互邏輯,但是在該代理類中,需要保證每次有回調(diào)的交互都能正確回調(diào)(不管是狀態(tài)為成功的回調(diào),還是狀態(tài)為失敗的回調(diào))文章來源地址http://www.zghlxwxcb.cn/news/detail-432525.html

import android.os.Handler
import android.os.Looper
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

const val TEST_CHANNEL_NAME = "zzq.channel.TestChannelProxy"

class TestChannelProxy(messenger: BinaryMessenger) : MethodChannel.MethodCallHandler {
    private val channel: MethodChannel

    init {
        channel = MethodChannel(messenger, TEST_CHANNEL_NAME)
        channel.setMethodCallHandler(this)
    }

    // ------------------------------ flutter 調(diào)用 native ------------------------------

    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        val args = call.arguments
        when (call.method) {
            "doSomethingAndListener" -> TestTool.doSomethingAndListener()
            else -> result.notImplemented()
        }
    }
    
    /*fun closeChannel() {
        channel.setMethodCallHandler(null)
        TestTool.closeChannel()
    }*/

    // ------------------------------ native 調(diào)用 flutter ------------------------------

    /**
     * Methods marked with @UiThread must be executed on the main thread. Current thread: AsyncTask
     */
    private fun mainInvokeMethod(method: String, arguments: Any?, callback: MethodChannel.Result?) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            channel.invokeMethod(method, arguments, callback)
        } else {
            Handler(Looper.getMainLooper()).post {
                channel.invokeMethod(method, arguments, callback)
            }
        }
    }

    fun getString(callback: (string: String?) -> Unit) {
        mainInvokeMethod(
            "getString",
            null,
            object : MethodChannel.Result {
                override fun success(result: Any?) {
                    callback(if (result is String) result else null)
                }

                override fun error(code: String, msg: String?, details: Any?) {
                    callback(null)
                }

                override fun notImplemented() {
                    callback(null)
                }
            })
    }

    fun getBoolean(callback: (boolean: Boolean) -> Unit) {
        mainInvokeMethod(
            "getBoolean",
            null,
            object : MethodChannel.Result {
                override fun success(result: Any?) {
                    callback(result == true)
                }

                override fun error(code: String, msg: String?, details: Any?) {
                    callback(false)
                }

                override fun notImplemented() {
                    callback(false)
                }
            })
    }

    fun onTestFirst(result: String) {
        mainInvokeMethod("onTestFirst", result, null)
    }

    fun onTestSecond() {
        mainInvokeMethod("onTestSecond", null, null)
    }

    fun onTestThird(result: Boolean, callback: (success: Boolean) -> Unit) {
        mainInvokeMethod(
            "onTestThird",
            result,
            object : MethodChannel.Result {
                override fun success(result: Any?) {
                    callback(result == true)
                }

                override fun error(code: String, msg: String?, details: Any?) {
                    callback(false)
                }

                override fun notImplemented() {
                    callback(false)
                }
            })
    }
}

到了這里,關(guān)于Flutter 與第三方 Native-SDK 的交互代理方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 記錄--@click和@click.native有什么區(qū)別,如何阻止第三方組件內(nèi)部的冒泡

    記錄--@click和@click.native有什么區(qū)別,如何阻止第三方組件內(nèi)部的冒泡

    vue @click.native 原生點擊事件: 1,給vue組件綁定事件時候,必須加上native ,不然不會生效(監(jiān)聽根元素的原生事件,使用 .native 修飾符) 2,等同于在子組件中: 子組件內(nèi)部處理click事件然后向外發(fā)送click事件: $emit(\\\"click\\\".fn) 不多說看代碼: 直接在封裝組件上使用@click,看看

    2024年02月10日
    瀏覽(21)
  • Flutter:第三方常用庫整理

    Flutter:第三方常用庫整理

    隨著Flutter的不斷學(xué)習(xí),接觸了不少第三方的庫。因此打算進行簡單的整理。 簡介 一個強大的Dart/FlutterHTTP客戶端,支持全局配置, 攔截器、表單數(shù)據(jù)、請求取消、文件上傳/下載、 超時和自定義適配器等。 官方地址 https://pub-web.flutter-io.cn/packages/dio 簡單使用 flutter:網(wǎng)絡(luò)請求

    2024年02月16日
    瀏覽(30)
  • Flutter 第三方 flutter_screenutil(屏幕適配)

    Flutter 第三方 flutter_screenutil(屏幕適配)

    推薦一篇寫的非常不過的文章:Flutter應(yīng)用框架搭建(二)屏幕適配 iPhone 12 mini 初始化 - 設(shè)置參考尺寸1 ScreenUtilInit 初始化 - 設(shè)置方式2 ScreenUtil.init 可以在每個頁面設(shè)置 使用這種方式只需在使用 flutter_screenutil 前進行初始化即可,一般放在根路由即第一個頁面加載的時候進行初始化

    2024年02月19日
    瀏覽(17)
  • 安卓APP引入第三方SDK如何做安全檢測?

    最近聽說好多App都被下架處理了,隱私合規(guī)管理特別嚴格。隔壁王老板公司旗下的一款A(yù)pp就被通報了,說是嵌入的第三方SDK違規(guī)收集用戶個人信息。 還記得,在2021年的315晚會,上海、北京有幾家公司都被報道,其SDK均在未經(jīng)用戶授權(quán),竊取用戶個人信息。涉案App有 50多款,

    2024年02月05日
    瀏覽(22)
  • 【第三方SDK接入?yún)R總】Unity接入VuforiaAR(圖片識別)

    【第三方SDK接入?yún)R總】Unity接入VuforiaAR(圖片識別)

    目錄 一.注冊Vuforia賬號 二.獲取許可秘鑰 三.獲取Vuforia的SDK導(dǎo)入unity 四.搭建創(chuàng)建AR場景 五.打包到手機 注冊地址:Engine Developer Portal 申請地址:https://developer.vuforia.com/vui/develop/licenses 方式一:?官網(wǎng)下載 下載地址:SDK Download | Engine Developer Portal? 下載后把package包導(dǎo)入unity即可。

    2024年04月08日
    瀏覽(31)
  • Flutter插件引入第三方j(luò)ar包之a(chǎn)rmeabi

    Flutter插件引入第三方j(luò)ar包之a(chǎn)rmeabi

    然而我們這個相機廠商只提供 armeabi 架構(gòu)的包 由于測試機是v8a的架構(gòu),而且flutter經(jīng)過多個版本更新后,不能直接flutter run的時候指定平臺架構(gòu)為32位的,則 無法調(diào)用到so文件 ,所以有不小的麻煩。這先按下不表。 首先還是在 plugin/android 的目錄新建一個 libs 文件夾,然后將

    2024年04月16日
    瀏覽(50)
  • Xcode通過Add package自動集成第三方SDK問題匯總

    Xcode通過Add package自動集成第三方SDK問題匯總

    問題1: ?解決方法:這個問題可能是因為 Adjust 或者 Facebook 的庫當中依賴的某些類庫的倉庫地址是 git:// 協(xié)議,通過這種協(xié)議與 GitHub 通訊時會使用到你的 SSH 配置,你電腦上相關(guān)的 ssh key 使用了 GitHub 不再支持的格式,請參考提示中的網(wǎng)址重新生成相關(guān)的 SSH key:https://githu

    2024年02月13日
    瀏覽(90)
  • ESP32工程中CMake使用及加入第三方SDK庫文件

    ESP32工程中CMake使用及加入第三方SDK庫文件

    ? ? ? ? 本文中使用的是樂鑫官方推出的 ESP-IDF v5.1 對 ESP32S3 設(shè)備開發(fā),并非是Arduino、Micro-python等第三方工具開發(fā)。在ESP-IDF框架中,樂鑫官方已經(jīng)將 CMake 和 Ninja 編譯構(gòu)建工具 集成到了ESP-IDF中。 ????????ESP-IDF 即樂鑫物聯(lián)網(wǎng)開發(fā)框架,可為在 Windows、Linux 和 macOS 系統(tǒng)平臺

    2024年02月20日
    瀏覽(99)
  • Flutter 應(yīng)用間跳轉(zhuǎn)應(yīng)用,實現(xiàn)喚起第三方App

    最近因為工作需求,做了應(yīng)用間跳轉(zhuǎn)應(yīng)用,因為是一個flutter新手,所以在工作之余隨便總結(jié)記錄一下。 1.使用第三方用戶登錄,跳轉(zhuǎn)到需授權(quán)的App。如QQ登錄,微信登錄等。需要用戶授權(quán),還需要\\\"返回到調(diào)用的程序,同時返回授權(quán)的用戶名、密碼\\\"。 2.應(yīng)用程序推廣,跳轉(zhuǎn)到

    2024年02月05日
    瀏覽(94)
  • vscode配置flutter開發(fā)環(huán)境,不需要安裝第三方安卓模擬器

    vscode配置flutter開發(fā)環(huán)境,不需要安裝第三方安卓模擬器

    點擊下方的安裝包,獲取 stable 發(fā)行通道的 Flutter SDK 最新版本:Flutter SDK 將壓縮包解壓,然后把其中的 flutter 目錄整個放在你想放置 Flutter SDK 的路徑中**(注意不要出現(xiàn)中文目錄)** 配置Windows系統(tǒng)的環(huán)境變量,在 用戶變量 一欄中,在Path中添加 flutterbin 目錄的完整路徑。例

    2024年02月10日
    瀏覽(39)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包