Flutter项目如何将任务调度到后台线程?
在Android中,如果你想访问网络资源,但又不想阻塞主线程,避免ANR,通常会把任务放在后台线程中。例如,您可以使用 AsyncTask、LiveData、IntentService、JobScheduler 任务或使用调度程序通过 RxJava 管道将任务切换到后台线程。
因为Flutter使用单线程并运行事件循环(类似于),所以您不需要担心线程管理和创建后台线程。如果您正在执行 I/O 密集型任务,例如存储访问或网络请求,则可以安全无忧地使用 async/await。另一个例子,您需要执行使用 CPU 的计算密集型工作,那么您可以将其移至 Isolate,这样它就不会阻塞事件循环,就像您将任务放在 Android 主线程之外一样。
对于I/O密集型任务,将方法声明为异步,并在方法中等待长时间运行的任务:
content_copy
loadData() async { String dataURL = ""; http.Response response = await http.get(dataURL); setState(() { widgets = (); }); }
这是您应该如何执行网络和数据库操作,所有这些操作都包括操作输入/输出。
在Android中,继承AsyncTask时,通常会重写三个方法,onPreExecute()、doInBackground()和onPostExecute()。 Flutter中没有对应的API。大部分时间你只需要等待方法调用,Dart 的事件循环将为你处理剩下的事情。
但是,有时您需要处理大量数据并挂起您的 UI。在 Flutter 中,您可以通过使用 Isolate 来利用多核处理器来执行耗时或计算密集型任务。
Isolate是独立执行的线程,不与主执行内存堆共享内存。这意味着您无法从主线程访问变量,或调用 setState() 来更新 UI。与 Android 中的线程不同,隔离,顾名思义,不能共享内存(例如通过静态变量)。
下面的示例展示了一个简单的 Isolate 如何将数据共享到主线程以更新 UI。
content_copy
loadData() async { ReceivePort receivePort = ReceivePort(); await Isolate.spawn(dataLoader, ); // The 'echo' isolate sends its SendPort as the first message. SendPort sendPort = await receivePort.first; List msg = await sendReceive(sendPort, ""); setState(() { widgets = msg; }); } // The entry point for the isolate. static dataLoader(SendPort sendPort) async { // Open the ReceivePort for incoming messages. ReceivePort port = ReceivePort(); // Notify any other isolates what port this isolate listens to. sendPort.send(); await for (var msg in port) { String data = msg[0]; SendPort replyTo = msg[1]; String dataURL = data; http.Response response = await http.get(dataURL); // Lots of JSON to parse replyTo.send(()); } } Future sendReceive(SendPort port, msg) { ReceivePort response = ReceivePort(); ([msg, ]); return response.first; }
DataLoader() 这里的 Isolate 在它自己的执行线程中运行。在 Isolate 中,您可以执行其他 CPU 密集型操作(例如解析大型 JSON 数据),或执行计算密集型数学操作(例如加密或信号处理)。
您可以打开下面的完整示例:
content_copy
import 'dart:convert'; import 'package:flutter/'; import 'package:http/' as http; import 'dart:async'; import 'dart:isolate'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: , ), home: SampleAppPage(), ); } } class SampleAppPage extends StatefulWidget { SampleAppPage({Key key}) : super(key: key); @override _SampleAppPageState createState() =< _SampleAppPageState(); } class _SampleAppPageState extends State>SampleAppPage< { List widgets = []; @override void initState() { (); loadData(); } showLoadingDialog() { if (widgets.length == 0) { return true; } return false; } getBody() { if (showLoadingDialog()) { return getProgressDialog(); } else { return getListView(); } } getProgressDialog() { return Center(child: CircularProgressIndicator()); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Sample App"), ), body: getBody()); } ListView getListView() =< ListView.builder( itemCount: widgets.length, itemBuilder: (BuildContext context, int position) { return getRow(position); }); Widget getRow(int i) { return Padding(padding: (), child: Text("Row ${widgets[i]["title"]}")); } loadData() async { ReceivePort receivePort = ReceivePort(); await Isolate.spawn(dataLoader, ); // The 'echo' isolate sends its SendPort as the first message SendPort sendPort = await receivePort.first; List msg = await sendReceive(sendPort, ""); setState(() { widgets = msg; }); } // the entry point for the isolate static dataLoader(SendPort sendPort) async { // Open the ReceivePort for incoming messages. ReceivePort port = ReceivePort(); // Notify any other isolates what port this isolate listens to. sendPort.send(); await for (var msg in port) { String data = msg[0]; SendPort replyTo = msg[1]; String dataURL = data; http.Response response = await http.get(dataURL); // Lots of JSON to parse replyTo.send(()); } } Future sendReceive(SendPort port, msg) { ReceivePort response = ReceivePort(); ([msg, ]); return response.first; } }
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。