移動應用程序開發的未來:Flutter

作者:Eric Grandt

隨着系統以及應用複雜性的日益增高,「write once,run anywhere」開始成爲越來越多開發工具的終極目標。

基於此,Google 於 2017 年的 I/O 大會上隆重推出了移動 UI 框架 Flutter,可以讓開發者在 iOS 和 Android 系統上快速構建高質量的原生用戶界面。與此同時,蘋果也於2019年 WWDC 爲開發者們帶來了一套可橫跨蘋果幾大操作系統的 UI 框架 SwiftUI。

那麼在此趨勢下,類似 Flutter 的這種工具真的是新一代移動開發的未來嗎?

幾年前,我在Android和iOS開發中略有涉足,使用的是Java和Objective-C。在花了大約一個月的時間學習後,我決定不再深入學習了。我就是無法找到那種深入其中的狀態。

但最近,我瞭解了Flutter,並決定在移動應用程序開發方向上再試上一試。我當即就愛上了它,因爲它使開發多平臺應用程序變得賊有趣。自從瞭解它以來,我已經使用它創建了一個app和一個庫。Flutter似乎是一個非常有前景的一步,下面我想解釋一下我之所以相信這一點的幾方面的原因。

一、由Dart提供技術支持

Flutter使用的是由谷歌開發的Dart語言。如果你之前使用過Java,那麼會比較熟悉Dart的語法,因爲它們非常相似。但除了語法之外,Dart跟Java就很不同了。

我不打算深入討論Dart,以免跑題,但我想討論一下我認爲它最有用的功能。這個功能就是異步操作。Dart不僅支持異步操作,而且還使其變得非常容易。

如果你正在進行IO或其他耗時的操作(例如查詢數據庫),那麼你有可能在所有Flutter應用程序中使用異步操作。如果沒有異步操作,任何耗時的操作都會導致程序凍結直到此操作完成。爲了防止這種情況,Dart爲我們提供了async和await關鍵字,以允許我們的程序在等待這些較長操作完成的過程中繼續往下執行。

讓我們看看幾個例子:一個有異步操作,一個沒有。

// Without asynchronous operations
import 'dart:async';

main() {
    longOperation();
    printSomething();
}

longOperation() {
    Duration delay = Duration(seconds: 3);
    Future.delayed(delay);
    print('Waited 3 seconds to print this and blocked execution.');
}

printSomething() {
    print('That sure took a while!');
}

輸出 t :

Waited 3 seconds to print this and blocked execution.
That sure took a while!

這不太理想。沒人會想用在執行長時間操作時會卡住的App。所以讓我們稍微修改一下並使用async和await關鍵字。

// With asynchronous operations
import 'dart:async';

main() {
    longOperation();
    printSomething();
}

Future<void> longOperation() async {
    var retVal = await runLongOperation();

    print(retVal);
}

const retString = 'Waited 3 seconds to return this without blocking execution.';
Duration delay = Duration(seconds: 3);

Future<String> runLongOperation() => Future.delayed(delay, () => retString);

printSomething() {
    print('I printed right away!');
}

並再次輸出:

I printed right away!
Waited 3 seconds to return this without blocking execution.

有了異步操作,我們在執行需要比較久才能完成的代碼的同時,其餘代碼的執行也不會被妨礙。

二、只寫一次代碼,就能同時在Android和iOS上運行

考慮到需要爲Android和iOS使用不同的代碼庫,開發移動應用程序可能需要花費大量時間。除非您使用像Flutter這樣的SDK,這樣您就將擁有一個能適配兩個操作系統的代碼庫。不僅如此,你還可以完全原生地運行它們。這意味着諸如瀏覽頁面和導航之類的東西,完美配合不同的操作系統。

一言以蔽之,只要您有個設備或模擬器在運行着,Flutter就可以使構建和運行您的應用程序來進行測試的過程簡單到動動手指就能完成。

三、UI開發

UI開發幾乎是我最不期待的事情之一。我更像是一個後端開發人員,所以當涉及到嚴重依賴它的東西時,我只想要一些簡單的東西。這就是Flutter在我眼中閃耀的地方。

UI通過將不同的小部件組合在一起並修改它們以適合你的App外觀來創建。你幾乎可以完全控制這些小部件的顯示方式,因此你最終總是會得償所願。爲了佈局UI,可以使用諸如Row,Column和Container之類的小部件。對於內容,有諸如Text和RaisedButton之類。這只是Flutter提供的小部件中的幾個,除這些之外還有很多。使用這些小部件,我們可以構建一個非常簡單的UI:

@override
Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text('Flutter App'),
            centerTitle: true,
            elevation: 0,
        ),
        body: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
                Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                        Container(
                            child: Text('Some text'),
                        ),
                        Container(
                            child: RaisedButton(
                                onPressed: () {
                                    // Do something on press
                                },
                                child: Text('PRESS ME'),
                            ),
                        ),
                    ],
                ),
            ],
        ),
    );
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gcd7ipPE-1594103092983)(https://upload-images.jianshu.io/upload_images/22436740-905dc24af6484113?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

Flutter像一個擁有各種各樣道具的魔術師,使你能輕而易舉地構建App的主題。你可以通過手動更改字體,顏色,並逐個設置所有內容,但這需要太長時間了。相反,Flutter爲我們提供了一個名爲ThemeData的東西,它允許我們爲顏色,字體,輸入字段等等設值。此功能在保持應用外觀的一致性方面很出色。

theme: ThemeData(
    brightness: Brightness.dark,
    canvasColor: Colors.grey[900],
    primarySwatch: Colors.teal,
    primaryColor: Colors.teal[500],
    fontFamily: 'Helvetica',
    primaryTextTheme: Typography.whiteCupertino.copyWith(
        display4: TextStyle(
            color: Colors.white,
            fontSize: 36,
        ),
    ),
),

使用此ThemeData,我們設置應用程序顏色,字體系列和一些文本樣式。除文本樣式之外的所有內容都將自動應用於整個app範圍。每個小部件的文本樣式必須手動地一個一個設置,但這仍然很簡單:

child: Text(
    'Some text',
    style: Theme.of(context).primaryTextTheme.display4,
),

爲了進一步提高效率,Flutter可以熱重新加載應用程序,因此您無需在每次更改UI時重新打開它。您現在可以進行更改,保存,然後在大概一秒內就能看到更改後的效果。

四、庫

Flutter提供了許多開箱即用的強大功能,但有時你需要更多功能。考慮到Dart和Flutter的大量可用的庫,這根本不是問題。是否有興趣在你的應用中投放廣告?有這方面的庫。想要新的小部件嗎?有這方面的庫。

如果你更喜歡自己動手DIY,可以創建自己的庫並馬上就能與社區其他人分享。向項目添加庫很簡單,可以通過向pubspec.yaml文件添加一行代碼來完成。例如,如果要添加sqflite庫:

dependencies:
  flutter:
    sdk: flutter
  sqflite: ^1.0.0

將它添加到文件後,運行flutter packages get,這樣就好了。各種各樣的庫使開發Flutter應用程序變得輕而易舉,併爲開發過程節省了大量時間。

五、後端開發

現在大多數App都依賴於某種數據,所有這些數據需要存儲在某個地方,以便以後可以顯示和使用。因此,在尋找使用新SDK(例如Flutter)創建應用時,牢記這一點非常重要。

再重複一次,Flutter App是使用Dart製作的,而Dart在後端開發方面非常出色。我在本文中談到了很多簡單易行的功能,Dart和Flutter的後端開發也不例外。不管是對於初學者還是專家,創建數據驅動的App都非常簡單,但這種簡單性並不等同於質量底下。

可以使用庫,以便你使用所選擇的數據庫。使用sqflite庫,我們可以非常快速地啓動並運行SQLite數據庫。感謝單件模式,我們可以訪問數據庫並從幾乎任何地方都可以進行查詢,而無需每次都重新創建一個對象。

class DBProvider {
    // Singleton
    DBProvider._();

    // Static object to provide us access from practically anywhere
    static final DBProvider db = DBProvider._();
    Database _database;

    Future<Database> get database async {
        if (_database != null) {
            return _database;
        }

        _database = await initDB();
        return _database;
    }

    initDB() async {
        // Retrieve your app's directory, then create a path to a database for your app.
        Directory documentsDir = await getApplicationDocumentsDirectory();
        String path = join(documentsDir.path, 'money_clip.db');

        return await openDatabase(path, version: 1, onOpen: (db) async {
            // Do something when the database is opened
        }, onCreate: (Database db, int version) async {
            // Do something, such as creating tables, when the database is first created.
            // If the database already exists, this will not be called.
        }
    }
}

從數據庫中檢索數據後,可以使用一個模型將其轉換爲對象。或者,如果要將對象存儲在數據庫中,可以使用相同的模型將其轉換爲JSON。

class User {
    int id;
    String name;

    User({
        this.id,
        this.name,
    });

    factory User.fromJson(Map<String, dynamic> json) => new User(
        id: json['id'],
        name: json['name'],
    );

    Map<String, dynamic> toJson() => {
        'id': id,
        'name': name,
    };
}

如果沒有將其顯示給用戶的方法,這些數據就不是那麼有用了。這就是Flutter帶着諸如FutureBuilder或StreamBuilder這樣的小部件登場的時候了。如果您對使用Flutter,SQLite和其他技術來創建數據驅動型App有興趣做更深一步的瞭解,我建議你查看這方面的文章:

六、最後的一些思考

有了Flutter,就有了幾乎無窮無盡的可能性,因此即使是體量巨大的App也可以輕鬆地被創建出來。如果你是做移動App開發的並且尚未嘗試過Flutter,我強烈建議你試一下,因爲我相信你也會愛上它的。使用Flutter幾個月之後,我認爲可以說這是移動開發的未來。如果不能算未來的話,這也絕對是朝着正確方向邁出去的一步。

最最最後

在這裏我也分享一份由幾位大佬一起收錄整理的Android學習PDF+架構視頻+面試文檔+源碼筆記高級架構技術進階腦圖、Android開發面試專題資料,高級進階架構資料

這些都是我閒暇還會反覆翻閱的精品資料。可以有效的幫助大家掌握知識、理解原理。當然你也可以拿去查漏補缺,提升自身的競爭力。

如果你有需要的話,可以 點這領取

喜歡本文的話,不妨順手給我點個小贊、評論區留言或者轉發支持一下唄~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章