Flutter 避免阻塞ui线程

import 'dart:async';
import 'dart:isolate';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _data = '';
  bool loading = true;

  @override
  void initState() {
    super.initState();
    _init();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: loading ? CircularProgressIndicator() : Text(_data),
      ),
    );
  }

  Future<void> _init() async {
    final worker = Worker();
    await worker.isReady;
    var data = await worker.getData();
    setState(() {
      _data = data;
      loading = false;
    });
    worker.dispose();
  }
}

class Worker {
  Isolate _isolate;

  /// 发送端口
  SendPort _sendPort;

  /// 接收端口
  ReceivePort _receivePort;

  final _isReady = Completer<void>();
  Future<void> get isReady => _isReady.future;

  final _data = Completer<String>();
  Future<String> get data => _data.future;

  Worker() {
    _init();
  }
  Future<void> _init() async {
    _receivePort = ReceivePort()..listen(_handleMessage);

    _isolate = await Isolate.spawn(
      _isolateEntry,
      _receivePort.sendPort,
    );
  }

  Future<String> getData() {
    _sendPort.send(null);
    return data;
  }

  void _handleMessage(dynamic message) {
    if (message is SendPort) {
      _sendPort = message;
      _isReady.complete();
      return;
    }
    _data.complete(message);
  }

  static void _isolateEntry(dynamic message) {
    SendPort sendPort;
    final receivePort = ReceivePort()
      ..listen((dynamic message) async {
        await Future.delayed(Duration(seconds: 1));
        var r = await http.get('http://192.168.0.104:3000');
        sendPort.send(r.body);
      });

    if (message is SendPort) {
      sendPort = message;
      sendPort.send(receivePort.sendPort);
    }
  }

  dispose() {
    _isolate.kill();
  }
}
posted @ 2019-12-06 20:11  Ajanuw  阅读(2361)  评论(0编辑  收藏  举报