美文网首页Flutter实战
Flutter实战-请求封装(五)之Isolate线程改造

Flutter实战-请求封装(五)之Isolate线程改造

作者: 蓝面书生IT | 来源:发表于2022-08-08 11:41 被阅读0次

    用了两年的flutter,有了一些心得,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜谢~(原创不易,转发请标注来源和作者)

    注意:无特殊说明,flutter版本为3.0+

    Future 是Dart中常用的解决耗时操作的方案,一个async-await刚开始用的非常开心,但是后来发现了很多问题。在处理复杂业务逻辑的时候,页面请求非常多,耗时比较长,有时候UI开始变的卡顿,非常头疼。

    我们知道Dart是单线程的异步模型,Future只是异步任务,依然会阻塞线程。那么我们知道不管是在Android还是IOS原生中,我们都有多线程的概念,充分利用手机CPU来处理事务。那么Dart是如何进行多线程的呢,那就是isolate。

    一. isolate

    Isolate是Dart对actor并发模式的实现,类似于 Android 中的 Thread 线程,但与 Thread 有本质的区别,Thread 可以实现内存共享,而 Isolate 不能

    运行中的Dart程序由一个或多个actor组成,这些actor也就是Dart概念里面的isolate。Isolate 可以方便的利用多核 CPU 来处理耗时操作,因内存不共享,需要通过 Port 进行消息通讯;其中 Port 消息传递也是异步的;

    isolate 一般来解决耗时操作。


    二.dio 的isolate改造

    思路:将dio的基础信息,包括url,method,params,data等信息传入到isolate线程中去,然后将返回结果返回到住线程中。

    我们直接看源码

    class Resolve {
    static Future<dynamic> resolve(String method, Map<String, dynamic> data) async {
    ReceivePort receivePort = ReceivePort();
    final Isolate isolate = await Isolate.spawn(
    _entryPoint,
    _Message(data['baseUrl'], data['path'], method, data['params'] ?? {}, data['data'],
    receivePort.sendPort, data['headers']));

    var result = await receivePort.first;
    receivePort.close();
    isolate.kill();
    return result;
    }

    static void _entryPoint(_Message d) async {
    try {
    var res;
    if (d.method == "get") {
    res = await Http().get(d.path, baseUrl: d.baseUrl, params: d.params, headers: d.headers);
    res = ApiResponse.fromJson(res);
    }
    if (d.method == "post") {
    res = await Http().post(d.path, baseUrl: d.baseUrl, data: d.data, params: d.params, headers: d.headers);
    res = ApiResponse.fromJson(res is Map ? res : jsonDecode(res));
    }
    Isolate.exit(d.sendPort, res);
    } catch (e) {
    Isolate.exit(d.sendPort);
    }
    }
    }

    不过发现一个问题,每一个请求都会开启一个线程,创建线程本身开销非常大,反复创建和销毁,非常容易造成资源浪费,甚至由于线程过多导致app崩溃,那如何解决呢?

    三.LoadBalancer

    我们先看下定义

    /// A pool of runners, ordered by load.
    ///
    /// Keeps a pool of runners,
    /// and allows running function through the runner with the lowest current load.
    ///
    /// The number of pool runner entries is fixed when the pool is created.
    /// When the pool is [close]d, all runners are closed as well.
    ///
    /// The load balancer is not reentrant.
    /// Executing a [run] function should not *synchronously*
    /// call methods on the load balancer.
    class LoadBalancer implements Runner {

    简单的来说可以理解为线程池,有多线程经验的同学知道,线程池解决的核心问题是资源管理问题,介绍了开销,合理配置cup和内存,性能和稳定性会更强,下面我们看下如何改造。

    Future<LoadBalancer> loadBalancer = LoadBalancer.create(4, IsolateRunner.spawn);

    class Resolve {
    static Future<dynamic> resolve(String method, Map<String, dynamic> data) async {
    final LoadBalancer lb = await loadBalancer;
    var res = await lb.run<dynamic, _Message>(
    _entryPoint,
    _Message(
    data['baseUrl'], data['path'], method, data['params'] ?? {}, data['data'] ?? {}, data['headers']));
    return res;
    }
    }

    相关文章

      网友评论

        本文标题:Flutter实战-请求封装(五)之Isolate线程改造

        本文链接:https://www.haomeiwen.com/subject/nzhnwrtx.html