簡體   English   中英

如何在 Flutter 應用程序中初始化一個長期存在的類?

[英]How do I initialize a long-lived class in a Flutter app?

我有一個Api類,它接受一個(可選)身份驗證token ,它用於發出經過身份驗證的請求,例如Api(token: 'a9sa2ksas12').getUserDetails()

如果沒有傳遞令牌,它必須執行從sharedPreferences讀取它的相對昂貴的操作。

class Api {
  static const BASEURL = "https://api.google.com/";
  final String token;

  Api({ this.token });

  Future<http.response> getUserDetails() async {
    return http.get('$BASEURL/user/', headers: { 'Authorization': token });
  }
}

如何設置我的應用程序,以便令牌僅從sharedPreferences讀取一次並在整個應用程序中用於所有未來的Api()請求?

我考慮過並認為可能有效的一些想法:

  • token成為全局變量
  • 使 API 類成為單例,並在“屏幕”之間傳遞它

總的來說,讓您的Repositories成為單身人士並沒有什么不好。 但另一方面,我不喜歡在屏幕之間傳遞API類的概念。

widgets在沒有任何中間人的情況下直接使用您的數據源時,例如BlocProvider ,它們往往會受到大量表示邏輯的污染。 我個人更喜歡將這些關注點分開,讓小部件完成它們的用途:渲染 UI。 這使它們更小且更易於測試。

更重要的是API類應該只負責網絡調用。 它不應該負責管理令牌。 我會注入API類,例如:

class TokenProvider 
{
   Future<String> getToken();
}

你猜對了,這個類的職責是提供一個令牌。 它可以返回緩存值或從SharedPreferences獲取它。 多虧了這一點, API不必關心令牌的來源以及如何處理它。 它只會做一件事:api 調用。

我最終通過get_it使用了“定位器”模式。

代碼非常簡單。

第 1 步:在lib/設置頂級locator.dart

// ./lib/locator.dart
import 'package:my_app/services/api.dart';
import 'package:get_it/get_it.dart';

GetIt locator = GetIt.instance;

void setupLocator() {
  locator.registerLazySingleton(() => Api());
}

第 2 步:只需導入定位器,即可在應用程序的任何位置使用api

// ./lib/widgets/some_screen.dart
class _SomeScreenState extends State<SomeScreen> {
  Api api = locator<Api>();

  @override
  void initState() {
    api.getUserDetails().then((response) => {
      // do anything you like with the response
    });
    super.initState();
  }

這種方法的美妙之處在於Api在應用程序的生命周期內只初始化一次,所以我只需在initState上為其分配一個token ,而不必擔心小部件被處理/重建和重復獲取到 SharedPreferences。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM