Flutter:基于 Provider 實現(xiàn)多環(huán)境構建配置

建議使用 flutter_flavor 實現(xiàn)。

多環(huán)境構建配置,在實際的開發(fā)工作中是很有必要的。但是 Flutter 沒有類似 .env 的配置,所以,只能是另辟蹊徑。本文是總結網(wǎng)上一堆經(jīng)驗的一次實踐,上手相對簡單。

Production 模式 Development 模式

一、基本操作步驟

  • 安裝 Provider 依賴;
  • 拆分原有的 main.dart 為 2 個部分,一部分為 main(),一部分為 App() MaterialApp 組件;
  • 建立對應各個環(huán)境的入口文件,如:main_prod.dart、main_dev.dart;
  • 建立環(huán)境配置類 class Env(),給定默認參數(shù),并支持傳入新的配置參數(shù);
  • 建立狀態(tài)管理類 class StateEnv with ChangeNotifier
  • 在對應的入口中使用 Provider 掛載應用,并指定為對應的環(huán)境模式;
  • 在頁面中使用 Provider.of<StateEnv>(context) 的方式獲取"環(huán)境變量";
  • 啟動調(diào)試;

二、詳細步驟

以下是詳細操作步驟:

2.1 安裝 Provider 依賴

Provider 是 flutter 開發(fā)常用的一個狀態(tài)管理庫,參考官方的安裝教程安裝。

安裝 Provider 依賴

2.2 拆分原有的 main.dart

為了減少冗余代碼,我們將拆分原有的 main.dart 為 2 個部分:一部分為 main() 方法,一部分為 App() MaterialApp 組件;

// 拆分后的 ./lib/main.dart
// import 略···

// 這里 import 我們拆分后的 app.dart
import 'app.dart';

void main() {
  runApp(App());
}
// 新建 ./lib/app.dart,并粘貼原來實現(xiàn) MaterialApp 的代碼
// import 略···
class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      // 組件內(nèi)容略 ···
    );
  }
}

2.3 建立對應各個環(huán)境的入口文件

為不同的構建環(huán)境創(chuàng)建不同的入口文件,這里暫先創(chuàng)建 2 個入口,分別為 main_prod.dart、main_dev.dart,直接復制原來 main.dart的內(nèi)容到新建的兩個文件。

// ./lib/main_dev.dart
// import 略···

// 這里 import 我們拆分后的 app.dart
import 'app.dart';

void main() {
  runApp(App());
}

main_prod.dart 的文件內(nèi)容同上。

2.4 建立環(huán)境配置類 class Env()

我們需要建立一個通用配置文件,如:class Env,并根據(jù)不同的環(huán)境實例化它,如:開發(fā)環(huán)境 new Env( mode: 'dev' ),生產(chǎn)環(huán)境 new Env( mode: 'prod' ) 等。同時,為了統(tǒng)一管理,我還建立了一個環(huán)境枚舉 EnvMode./lib/utils/env.dart 是我們的環(huán)境配置類,具體文件內(nèi)容如下:

// ./lib/utils/env.dart
// 環(huán)境變量配置

// 環(huán)境標識
enum EnvMode {
  PRODUCTION, // 生產(chǎn)環(huán)境
  DEVELOPMENT, // 開發(fā)環(huán)境
  TEST, // 測試環(huán)境
  UAT, // 預發(fā)布環(huán)境
}

class Env {
  // 環(huán)境標識
  final EnvMode mode;

  // 接口參數(shù)
  final String api;

  // 應用基礎配置
  final String appName;

  Env({
    this.mode = EnvMode.PRODUCTION,
    this.api = '',
    this.appName = 'Flutter 學習',
  }) : super();
}
  • mode 是當前環(huán)境標識,可以使用類似 Env.mode == EnvMode.DEVELOPMENT 的方式判斷當前構建模式;
  • api 是當前模式使用的數(shù)據(jù)請求接口;
  • appName 是一個演示變量;

實際開發(fā)中,我們需要根據(jù)環(huán)境配置的內(nèi)容可遠不止這么多。

2.5 建立狀態(tài)管理類

Provider 需要一個支持狀態(tài)響應的類,建立一個 StateEnv 類,內(nèi)容如下:

// ./lib/state/state_env.dart
// 環(huán)境狀態(tài)配置
// import 略 ···

class StateEnv with ChangeNotifier {
  // 環(huán)境配置
  final Env config;

  StateEnv({this.config}) : super();

  // 獲取環(huán)境模式
  EnvMode get mode => this.config.mode;

  // 獲取接口配置
  String get api => this.config.api;

  // 獲取應用名稱
  String get appName => this.config.appName;
}

2.6 在對應的入口中使用 Provider 掛載應用;

接下來修改我們的入口文件,按照 Provider 的語法初始化即可。

// ./lib/main_dev.dart
void main() {
  // 實例化應用
  runApp(
    // 支持多個狀態(tài)管理
    MultiProvider(
      providers: [
        // 環(huán)境配置
        ChangeNotifierProvider(
          create: (BuildContext context) => StateEnv(
            config: Env(
              mode: EnvMode.DEVELOPMENT, // 使用開發(fā)環(huán)境
              api: 'http://127.0.0.1:3000', // 指定該環(huán)境對應的數(shù)據(jù)請求接口
            ),
          ),
        ),
      ],
      child: App(), // App 掛載
    ),
  );
}

2.7 在頁面中讀取配置

其他頁面可以使用 Provider.of<StateEnv>(context, listen: false) 訪問狀態(tài)中的值,如:

// 偽代碼
appBar: AppBar(
  title: Text(Provider.of<StateEnv>(context, listen: false).appName),
)
// ./lib/app.dart
class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: Provider.of<StateEnv>(context, listen: false).appName,
      debugShowCheckedModeBanner: Provider.of<StateEnv>(context).mode == EnvMode.DEVELOPMENT, // 是否顯示右上角 debug 徽標
      home: HomePage(),
    );
  }
}

2.8 啟動調(diào)試

以 IntelliJ IDEA 為例,只需要為不同的入口建立運行配置即可。

啟動調(diào)試
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容