前言

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

插件地址: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 ProxyThread new PThreadPoolExecutor

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

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

优化后:

Android 线程优化插件运用(第一篇)
咱们现已将sdk中new Thread 以及new ThreadPoolExecutor 相关代码都改了

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

的确,要想到达收敛的意图,还需求做一些工作,拿PThreadPoolExecutor 为例

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

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中增加如下的配置
apply plugin: 'LancetX'
LancetX{
    enable true
    enableInDebug true
    weaveGroup {
        threadOptimize {
            enable false
            whiteNames = [
                    "com/bb",
                    "com/aa",
                    "com/xx"
            ]
            blackNames = [
            ]
        }
    }
}

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

threadOptimize { // 线程优化配置项
enable true  // 开关
    whiteNames = [   // 白名单,咱们可以增加白名单,来指定特定的几个sdk来进行线程优化
            "com/bb",
            "com/aa",
            "com/xx"
    ]
    blackNames = [  // 黑名单
    ]
} 
  • 最后一步便是来完成 咱们自己的ProxyThread PThreadPoolExecutor 代码了,以及 ThreadProxyThread的映射,ThreadPoolExecutorPThreadPoolExecutor的映射

也便是咱们要告知字节码修正插件,咱们想要修正哪些类,比方咱们即将修正 Thread 类,修正为 ProxyThread,代码如下图。

另外 ProxyThreadPThreadPoolExecutorgetHCoreThreadPool()的完成都已在库房中了

注意点

线程收敛到这儿其实还没开始,由于真实重要的是咱们的代理线程池的参数应该怎么配置。

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

  • 线程池核心线程数
  • 线程池最大线程数
  • 使命等待行列
  • 线程空闲多久要收回,也便是keepAliveTime
  • 线程使命拒绝战略的拟定 RejectedExecutionHandler

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