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前端网发表,如需转载,请注明页面地址。
code前端网



发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。