Android 线程优化插件使用(第一篇)

前言

本插件内容是结合多家博客的精华改造而成的

插件地址:github.com/heyan224/la...

该插件主要是基于github.com/Knight-ZXW/... 的基础上细化改造的

目标

线程优化就是将自己代码中的线程以及各种sdk 中创建的线程都收敛到统一的线程池中,方便线程的管理。

我们知道创建线程的方式有多种:

  • new Thread
  • new ScheduledThreadPoolExecutor
  • new ThreadPoolExecutor
  • new FixedThreadPool
  • new CachedThreadPool
  • Executors.newSingleThreadExecutor()
  • new HandlerThread

随着业务的膨胀以及接入各种三方sdk越来越多,那么在我们的apk中将存在大量无法管控的Thread实例以及 ThreadPoolExecutor 实例。

所以要达到线程收敛的目的就是要将 各种 new Thread 以及new ThreadPoolExecutor 等等实例都变成 一个 ,比如new ProxyThreadnew PThreadPoolExecutor

以某一个sdk为例,线程收敛前某sdk的现状如下:

优化后:

我们已经将sdk中new Thread 以及new ThreadPoolExecutor 相关代码都改了

问题来了,即使都改成了new ProxyThread new PThreadPoolExecutor,这不是依然有很多线程和线程池的实例吗,依然没有达到收敛的目的?

确实,要想达到收敛的目的,还需要做一些事情,拿PThreadPoolExecutor 为例

我们在PThreadPoolExecutor 重写了ThreadPoolExecutor中的 execute 方法和 submit方法,当有人向线程池中提交任务时,我们这里并没有开启线程,而是通过 DefaultThreadPoolExecutor.getHCoreThreadPool ().execute(command) 将任务丢到了新的线程池中。 所以可以看出PThreadPoolExecutor 并不是真正的线程池,真正的线程池是 getHCoreThreadPool(),它是一个单例。

kotlin 复制代码
public class PThreadPoolExecutor  extends ThreadPoolExecutor {
//..........
//.........

    @Override
    public void execute(Runnable command) {
        if (!SuperThreadPoolManager.isProxyThreadEnable()) {
            super.execute(command);
            return;
        }
        try {
            DefaultThreadPoolExecutor.getHCoreThreadPool().execute(command);
        } catch (OutOfMemoryError error) {
            DefaultThreadPoolExecutor.getExtraThreadPool().execute(command);
        }
    }


    @Override
    public Future<?> submit(Runnable task) {
        if (!SuperThreadPoolManager.isProxyThreadEnable()) {
            return super.submit(task);
        }

        try {
            return DefaultThreadPoolExecutor.getHCoreThreadPool().submit(task);
        } catch (OutOfMemoryError error) {
            return DefaultThreadPoolExecutor.getExtraThreadPool().submit(task);
        }
    }


    @Override
    public <T> Future<T> submit(Callable<T> task) {
        if (!SuperThreadPoolManager.isProxyThreadEnable()) {
            return super.submit(task);
        }
        try {
            return DefaultThreadPoolExecutor.getHCoreThreadPool().submit(task);
        } catch (OutOfMemoryError error) {
            return DefaultThreadPoolExecutor.getExtraThreadPool().submit(task);
        }

    }
}

使用

  • 项目的根目录下的build.gradle中添加

classpath 'io.github.heyan224:lancet-plugin:0.0.6'

  • app目录下的build.gradle中添加

implementation 'io.github.heyan224:lancet-runtime:0.0.2'

  • 还是在 app目录下的build.gradle中添加如下的配置
bash 复制代码
apply plugin: 'LancetX'
LancetX{
    enable true
    enableInDebug true

    weaveGroup {

        threadOptimize {
            enable false
            whiteNames = [
                    "com/bb",
                    "com/aa",
                    "com/xx"
            ]
            blackNames = [

            ]
        }

    }
}

这里解释几个关键的字段:

arduino 复制代码
threadOptimize { // 线程优化配置项
enable true  // 开关
    whiteNames = [   // 白名单,我们可以添加白名单,来指定特定的几个sdk来进行线程优化
            "com/bb",
            "com/aa",
            "com/xx"
    ]
    blackNames = [  // 黑名单

    ]
} 
  • 最后一步就是来实现 我们自己的ProxyThread PThreadPoolExecutor 代码了,以及 ThreadProxyThread的映射,ThreadPoolExecutorPThreadPoolExecutor的映射

也就是我们要告诉字节码修改插件,我们想要修改哪些类,比如我们将要修改 Thread 类,修改为 ProxyThread,代码如下图。

另外 ProxyThreadPThreadPoolExecutorgetHCoreThreadPool()的实现都已在仓库中了

注意点

线程收敛到这里其实还没开始,因为真正重要的是我们的代理线程池的参数应该如何配置。

我们都知道线程池有几个重要的参数需要深思熟虑

  • 线程池核心线程数
  • 线程池最大线程数
  • 任务等待队列
  • 线程空闲多久要回收,也就是keepAliveTime
  • 线程任务拒绝策略的制定 RejectedExecutionHandler

这几个参数的制定对于线程收敛很重要。

相关推荐
夜雨深秋来1 小时前
多租户 AI Agent 平台架构设计与实践
架构·langchain·agent
赏金术士3 小时前
Kotlin 从入门到进阶 之作用域函数 & 优雅写法(五)
android·开发语言·kotlin
却尘4 小时前
让 AI 不再写到一半就开始"编":SDD + OpenSpec 上手指南
架构
Ehtan_Zheng5 小时前
Android Compose 动画实践:内容切换与页面转场
android
Crystal3285 小时前
【终极指南】前端方面解决 uni-app APP 端 SSE 流式请求被缓冲拦截、无法实时渲染的问题
android·前端·ai编程
梦梦代码精6 小时前
LikeShop 二次开发扩展能力白皮书——面向业务增长的可扩展电商架构实践
java·架构·github
该昵称用户已存在6 小时前
从单体到微服务・从本地到云端:MyEMS 开源系统的架构演进与落地优势
微服务·架构·开源
IPHWT 零软网络6 小时前
OM200G-A融合通信IP-PBX:国产化架构下的高可靠政企通信解决方案
网络协议·tcp/ip·架构
陆业聪7 小时前
技术选型决策树:什么团队、什么项目该选什么框架 | 跨平台框架深度对决(4)
android·架构设计
2501_912784087 小时前
TaoCarts 反向海淘系统架构实战:1688代采与高并发缓存设计全解析
缓存·架构·系统架构·跨境电商·taocarts