Android中创建多线程管理器实例

 更新时间:2014年06月26日 09:22:17   作者:冰冻鱼  
这篇文章主要介绍了Android中创建多线程管理器实例,着重讲解需要做的哪些事情,每一步都配有代码例子,需要的朋友可以参考下

如果你要反复执行一个任务,用不同的数据集(参数不同),但一次只要一个执行(任务是单线程的),IntentService符合你的需求。当需要在资源可用时自动执行任务,或允许多任务同时执行,你需要一个线程管理器管理你的线程。ThreadPoolExecutor,会维护一个队列,当它的线程池有空时,从队列里取任务,并执行。要运行任务,你要做的就是把它加到队列里。

线程池可以并联运行一个任务的多个实例,所以你要保存代码线程安全。能被多线程访问的变量需要同步块.更多信息,见Processes and Threads(http://developer.android.com/guide/components/processes-and-threads.html)

定义线程池类

在它自己类中实例ThreadPoolExecutor.在类里,如下操作:

为线程池使用static变量

你可能在app里只需要一个单例的线程池,这是为了统一控制限制CPU或网络资源。如果你有不同的Runnable类型,你可能想要每种类型都有各自的线程池,但这些都可以放到一个单一的实例里。比如,你可以把它声明成全局变量:

复制代码 代码如下:

public class PhotoManager {
    ...
    static  {
        ...
        // Creates a single static instance of PhotoManager
        sInstance = new PhotoManager();
    }
    ...

使用private构造方法

把构造方法声明成private,可以确保单例,这意味着你不需要在同步代码块里封装类访问。

复制代码 代码如下:

 public class PhotoManager {
        ...
        /**
         * 构建用来下载和decode图片的工作队列和线程池,因为构造方法标记为private,
         * 对其他类不可访问(甚至同包下的类)
         */
        private PhotoManager() {
            ...
        }

调用线程池类里的方法来开始任务

线程池类里定义一个方法,用来添加任务到线程池队列,如:

复制代码 代码如下:

public class PhotoManager {
    ...
    // 供PhotoView调用获取图片
    static public PhotoTask startDownload(
        PhotoView imageView,
        boolean cacheFlag) {
        ...
        // 添加一个任务到线程池
        sInstance.
                mDownloadThreadPool.
                execute(downloadTask.getHTTPDownloadRunnable());
        ...
    }

实例化一个UI线程的Handler.

Handler用于与UI线程通讯,大多数UI控件只允许在UI线程修改。

复制代码 代码如下:

private PhotoManager() {
    ...
        // Defines a Handler object that's attached to the UI thread
        mHandler = new Handler(Looper.getMainLooper()) {
            /*
             * handleMessage() defines the operations to perform when
             * the Handler receives a new Message to process.
             */
            @Override
            public void handleMessage(Message inputMessage) {
                ...
            }
        ...
        }
    }

判断线程池参数

一旦你有了全部类结构,你就可以开始定义线程池。实例化一个线程池对象,你需要下面的值:
初始池大小,最大池大小。
线程池的线程数量主要依赖于设备的CPU核心数.可以从系统环境中获取。

复制代码 代码如下:

public class PhotoManager {
...
    /*
     * Gets the number of available cores
     * (not always the same as the maximum number of cores)
     */
    private static int NUMBER_OF_CORES =
            Runtime.getRuntime().availableProcessors();
}

这个数字可能不能反映出设备的物理cpu内核数量;某些设备CPU会根据系统负载自动禁用部分内核,对于这些设备,availableProcessors()返回的是当前活跃的内核数量。

保持活跃时间和时间单位

一个进程在关闭前,保持空闲状态的时间(可以复用进程)。时间单位在TimeUnit里

任务队列

ThreadPoolExecutor的列队保存Runnable对象。在线程中执行代码,线程池管理器会从一个FIFO队列里取出一个Runnable对象,附加到线程里。队列实现BlockingQueue接口,在创建线程池时提供。你可以从现有实现中选一个,适应你的需求,参见ThreadPoolExecutor。下面是使用LinkedBlockingQueue的例子:

复制代码 代码如下:

public class PhotoManager {
    ...
    private PhotoManager() {
        ...
        // A queue of Runnables
        private final BlockingQueue<Runnable> mDecodeWorkQueue;
        ...
        // Instantiates the queue of Runnables as a LinkedBlockingQueue
        mDecodeWorkQueue = new LinkedBlockingQueue<Runnable>();
        ...
    }
    ...
}

创建线程池

调用ThreadPoolExecutor()方法初始化线程池。它会创建管理线程。因为线程池的初始大小和最大池大小是一样的,ThreadPoolExecutor在初始化时就创建了所有线程对象,如:

复制代码 代码如下:
    private PhotoManager() {
        ...
        // Sets the amount of time an idle thread waits before terminating
        private static final int KEEP_ALIVE_TIME = 1;
        // Sets the Time Unit to seconds
        private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
        // Creates a thread pool manager
        mDecodeThreadPool = new ThreadPoolExecutor(
                NUMBER_OF_CORES,       // Initial pool size
                NUMBER_OF_CORES,       // Max pool size
                KEEP_ALIVE_TIME,
                KEEP_ALIVE_TIME_UNIT,
                mDecodeWorkQueue);
    }

相关文章

  • Flutter实现局部刷新

    Flutter实现局部刷新

    这篇文章主要为大家详细介绍了Flutter实现局部刷新,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 浅谈RxJava+Retrofit+OkHttp 封装使用

    浅谈RxJava+Retrofit+OkHttp 封装使用

    本篇文章主要介绍了浅谈RxJava+Retrofit+OkHttp 懒人方式使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Android 使用 Path 实现搜索动态加载动画效果

    Android 使用 Path 实现搜索动态加载动画效果

    这篇文章主要介绍了Android 使用 Path 实现搜索动态加载动画效果,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下
    2018-08-08
  • Android 进入Activity时如何禁止弹出软键盘输入法

    Android 进入Activity时如何禁止弹出软键盘输入法

    这篇文章主要介绍了Android 进入Activity时如何禁止弹出软键盘输入法,文章围绕主题展开具体内容,需要的小伙伴可以参考一下
    2022-05-05
  • Android中的Choreographer工作原理解析

    Android中的Choreographer工作原理解析

    Choreographer作为Android系统中重要的组件,负责协调App进程的UI渲染与SurfaceFlinger进程的数据合成,本文详细分析了Choreographer的创建流程、VSYNC信号的调度和处理机制,揭示了其在UI渲染过程中的核心作用
    2024-10-10
  • Android实现万能自定义阴影控件实例代码

    Android实现万能自定义阴影控件实例代码

    这篇文章主要给大家介绍了关于Android实现万能自定义阴影控件的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • 详解Android中一些SQLite的增删改查操作

    详解Android中一些SQLite的增删改查操作

    这篇文章主要为大家详细介绍了Android中一些SQLLite的增删改查操作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Android 悬浮窗权限各机型各系统适配大全(总结)

    Android 悬浮窗权限各机型各系统适配大全(总结)

    这篇文章主要介绍了Android 悬浮窗权限各机型各系统适配大全(总结),具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Xposed插件开发入门详解

    Xposed插件开发入门详解

    这篇文章主要介绍了Xposed插件开发入门详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Android开发之ListView的简单用法及定制ListView界面操作示例

    Android开发之ListView的简单用法及定制ListView界面操作示例

    这篇文章主要介绍了Android开发之ListView的简单用法及定制ListView界面操作,结合实例形式分析了Android ListView界面布局相关操作技巧,需要的朋友可以参考下
    2019-04-04

最新评论