Flutter-填平菜鳥和高手之間的溝壑
準備寫作中...
1、Flutter-skia-影像,Flutter skia-圖形渲染層、應用渲染層
2、方法通道使用示例,用于演示如何使用方法通道實作與原生代碼的互動
需求:提示用戶跳轉到應用市場去評分
在實際業務中,提示用戶跳轉到應用市場(iOS 為 App Store、Android 則為各類手機應用市場)去評分是一個高頻需求,考慮到 Flutter 并未提供這樣的介面,而跳轉方式在 Android 和 iOS 上各不相同,因此我們需要分別在 Android 和 iOS 上實作這樣的功能,并暴露給 Dart 相關的介面,
我們先來看看作為客戶端的 Flutter,怎樣實作一次方法呼叫請求,實際上與呼叫一個 Dart 物件的方法完全一樣,
(1)首先,我們需要確定一個唯一的字串識別符號,來構造一個命名通道;
(2)然后,在這個通道之上,Flutter 通過指定方法名“openAppMarket”來發起一次方法呼叫請求,
(3)最后,因為方法呼叫程序是異步的,需要用非阻塞(或者注冊回呼)方式來等待原生代碼給予回應,
3、把發起方法呼叫請求的陳述句用 try-catch 包裝起來,處理例外
需要注意的是,與網路呼叫類似,方法呼叫請求有可能會失敗(比如,Flutter 發起了原生代碼不支持的 API 呼叫,或是呼叫程序出錯等),因此我們需要把發起方法呼叫請求的陳述句用 try-catch 包裝起來,
//宣告MethodChannel
const platform = MethodChannel('samples.chenhang/utils');
//處理按鈕點擊
handleButtonClick() async {
int result;
//例外捕獲
try {
//異步等待方法通道的呼叫結果
result = await platform.invokeMethod('openAppMarket');
} catch (e) {
result = -1;
}
print("Result:$result");
}
4、分別在 Android 和 iOS 兩個平臺上完成對應的介面實作,在原生代碼中完成方法呼叫的回應
呼叫方的實作搞定了,接下來就需要在原生代碼宿主中完成方法呼叫的回應實作了,由于我們需要適配 Android 和 iOS 兩個平臺,所以我們分別需要在兩個平臺上完成對應的介面實作,
首先,我們來看看 Android 端的實作方式,
(1)在上一小結最后我提到,在 Android 平臺,方法呼叫的處理和回應是在 Flutter 應用的入口,也就是在 MainActivity 中的 FlutterView 里實作的,因此我們需要打開 Flutter 的 Android 宿主 App,找到 MainActivity.java 檔案,并在其中添加相關的邏輯,
A、用 AS 打開 Flutter 專案 flutter_app_top_tab_03
B、然后,在 Flutter 專案 flutter_app_top_tab_03 中,右擊該專案的 android 子專案選擇用 Android 打開,如果直接在 Flutter 專案中撰寫安卓代碼,會有許多紅線報錯,也沒有安卓命令提示、無法用 Ctrl + Alt + L 進行代碼格式化
(2)呼叫方與回應方都是通過命名通道進行資訊互動的,所以我們需要在 onCreate 方法中,創建一個與呼叫方 Flutter 所使用的通道名稱一樣的 MethodChannel,并在其中設定方法處理回呼,回應 openAppMarket 方法,打開應用市場的 Intent,
(3)同樣地,考慮到打開應用市場的程序可能會出錯,我們也需要增加 try-catch 來捕獲可能的例外:
r:\FlutterProject\FlutterProject35\26_native_method\android\app\src\main\java\com\example\native_method\MainActivity.java
檔案內容:
package com.hangchen.native_method;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), "samples.chenhang/navigation").setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
// Note: this method is invoked on the main thread.
if(call.method.equals("openAppStore")) {
try {
Uri uri = Uri.parse("market://details?id=com.tencent.mm");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (Exception e) {
result.error("UNAVAILABLE", "沒有安裝應用市場", null);
}
}
else {
result.notImplemented();
}
}
});
}
}
5、在 Flutter 應用中通過呼叫 openAppMarket 方法,實作打開應用市場的功能,
需要注意的是,在 Flutter 使用方法通道進行方法呼叫和原生代碼回傳處理結果的程序中,存在傳輸資訊的序列化和反序列化,
接下來,我們就可以在 Flutter 應用里,通過呼叫 openAppMarket 方法,實作打開不同作業系統提供的應用市場功能了,
需要注意的是,在原生代碼處理完畢后將處理結果回傳給 Flutter 時,我們在 Dart、Android 和 iOS 分別用了三種資料型別:
Android 端回傳的是 java.lang.Integer、
iOS 端回傳的是 NSNumber、
Dart 端接收到回傳結果時又變成了 int 型別,
這是為什么呢?這是因為在使用方法通道進行方法呼叫時,由于涉及到跨系統資料互動,Flutter 會使用 StandardMessageCodec 對通道中傳輸的資訊進行類似 JSON 的二進制序列化,以標準化資料傳輸行為,這樣在我們發送或者接收資料時,這些資料就會根據各自系統預定的規則自動進行序列化和反序列化,
看到這里,你是不是對這樣類似網路呼叫的方法通道技術有了更深刻的印象呢,對于上面提到的例子,型別為 java.lang.Integer 或 NSNumber 的回傳值,先是被序列化成了一段二進制格式的資料在通道中傳輸,然后當該資料傳遞到 Flutter 后,又被反序列化成了 Dart 語言中的 int 型別的資料,
關于 Android、iOS 和 Dart 平臺間的常見資料型別轉換,我總結成了下面一張表格,幫助你理解與記憶,你只要記住,像 null、布爾、整型、字串、陣列和字典這些基本型別,是可以在各個平臺之間以平臺定義的規則去混用的,就可以了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/262768.html
標籤:Dart
下一篇:go get下載包失敗問題
