Android中关于项目中对Thread的管理(不是线程池)
背景
项目中对于一些并不复杂的耗时操作,比如计算,不频繁操作数据库等,因为没必要使用线程池,所以之前项目会直接使用new Thread的方式,时间一长,回头再看,原来new Thread之处已经很多了,这样带来了一些问题:
- 不断的new Thread,损耗性能。
- 在有生命周期的类(Activity或者Fragment或者Service)中,有可能出现内存泄漏。
- 缺乏统一管理,维护不方便。
分析
问题抛出了,就想办法解决吧。对于任务量小,操作不那么频繁的,我们只需要放在一个后台线程中即能满足要求,思路是只需要分门别类就可以了,对于操作数据库的,都使用data线程,对于计算相关的,都使用background线程,这样整个项目只需要维护几个固定后台线程。
注意:
- data 和background都是线程的名字,可以自己添加或者定义。
- 因为项目中已经维护了自己封装的线程池,所有涉及到下载,请求等大量I/O操作会使用线程池。
解决方案
自己封装了ThreadManager。
public class ThreadManager {
/** 主线程 */
public static final int THREAD_UI = 0;
/** background线程,用于一般的耗时操作 */
public static final int THREAD_BACKGROUND = 1;
/** data线程,用于数据库操作 */
public static final int THREAD_DATA = 2;
private static final int THREAD_SIZE = 3;
/** 线程信息数组 */
private static final Handler[] HANDLER_LIST = new Handler[THREAD_SIZE];
private static final String[] THREAD_NAME_LIST = {
"thread_ui",
"thread_background",
"thread_data"
};
private ThreadManager() {
HANDLER_LIST[THREAD_UI] = new Handler();
}
private static class ThreadManagerHolder {
private static ThreadManager sManager = new ThreadManager();
}
public static ThreadManager getManager() {
return ThreadManagerHolder.sManager;
}
/**
* 派发任务
*
* @param index 线程类型
*/
public void post(int index, Runnable r) {
postDelayed(index, r, 0);
}
/**
* 延迟派发任务
*
* @param index 线程类型
*/
public void postDelayed(int index, Runnable r, long delayMillis) {
Handler handler = getHandler(index);
handler.postDelayed(r, delayMillis);
}
/**
* 删除任务
*
* @param index 线程类型
*/
public void removeCallbacks(int index, Runnable r) {
Handler handler = getHandler(index);
handler.removeCallbacks(r);
}
/**
* 获取线程Handler
*
* @param index 线程类型
*/
public Handler getHandler(int index) {
if (index < 0 || index >= THREAD_SIZE) {
throw new InvalidParameterException();
}
if (HANDLER_LIST[index] == null) {
synchronized (HANDLER_LIST) {
if (HANDLER_LIST[index] == null) {
HandlerThread thread = new HandlerThread(THREAD_NAME_LIST[index]);
if (index != THREAD_UI) {
//优先级要低于主线程
thread.setPriority(Thread.MIN_PRIORITY);
}
thread.start();
Handler handler = new Handler(thread.getLooper());
HANDLER_LIST[index] = handler;
}
}
}
return HANDLER_LIST[index];
}
/**
* 判断是否运行在当前线程
*
* @param index 线程类型
* @return true yes
*/
public boolean runningOnCurrent(int index) {
return getHandler(index).getLooper() == Looper.myLooper();
}
}
注释一目了然,不做解释。
来自:
背景
项目中对于一些并不复杂的耗时操作,比如计算,不频繁操作数据库等,因为没必要使用线程池,所以之前项目会直接使用new Thread的方式,时间一长,回头再看,原来new Thread之处已经很多了,这样带来了一些问题:
- 不断的new Thread,损耗性能。
- 在有生命周期的类(Activity或者Fragment或者Service)中,有可能出现内存泄漏。
- 缺乏统一管理,维护不方便。
分析
问题抛出了,就想办法解决吧。对于任务量小,操作不那么频繁的,我们只需要放在一个后台线程中即能满足要求,思路是只需要分门别类就可以了,对于操作数据库的,都使用data线程,对于计算相关的,都使用background线程,这样整个项目只需要维护几个固定后台线程。
注意:
- data 和background都是线程的名字,可以自己添加或者定义。
- 因为项目中已经维护了自己封装的线程池,所有涉及到下载,请求等大量I/O操作会使用线程池。
解决方案
自己封装了ThreadManager。
public class ThreadManager {
/** 主线程 */
public static final int THREAD_UI = 0;
/** background线程,用于一般的耗时操作 */
public static final int THREAD_BACKGROUND = 1;
/** data线程,用于数据库操作 */
public static final int THREAD_DATA = 2;
private static final int THREAD_SIZE = 3;
/** 线程信息数组 */
private static final Handler[] HANDLER_LIST = new Handler[THREAD_SIZE];
private static final String[] THREAD_NAME_LIST = {
"thread_ui",
"thread_background",
"thread_data"
};
private ThreadManager() {
HANDLER_LIST[THREAD_UI] = new Handler();
}
private static class ThreadManagerHolder {
private static ThreadManager sManager = new ThreadManager();
}
public static ThreadManager getManager() {
return ThreadManagerHolder.sManager;
}
/**
* 派发任务
*
* @param index 线程类型
*/
public void post(int index, Runnable r) {
postDelayed(index, r, 0);
}
/**
* 延迟派发任务
*
* @param index 线程类型
*/
public void postDelayed(int index, Runnable r, long delayMillis) {
Handler handler = getHandler(index);
handler.postDelayed(r, delayMillis);
}
/**
* 删除任务
*
* @param index 线程类型
*/
public void removeCallbacks(int index, Runnable r) {
Handler handler = getHandler(index);
handler.removeCallbacks(r);
}
/**
* 获取线程Handler
*
* @param index 线程类型
*/
public Handler getHandler(int index) {
if (index < 0 || index >= THREAD_SIZE) {
throw new InvalidParameterException();
}
if (HANDLER_LIST[index] == null) {
synchronized (HANDLER_LIST) {
if (HANDLER_LIST[index] == null) {
HandlerThread thread = new HandlerThread(THREAD_NAME_LIST[index]);
if (index != THREAD_UI) {
//优先级要低于主线程
thread.setPriority(Thread.MIN_PRIORITY);
}
thread.start();
Handler handler = new Handler(thread.getLooper());
HANDLER_LIST[index] = handler;
}
}
}
return HANDLER_LIST[index];
}
/**
* 判断是否运行在当前线程
*
* @param index 线程类型
* @return true yes
*/
public boolean runningOnCurrent(int index) {
return getHandler(index).getLooper() == Looper.myLooper();
}
}
注释一目了然,不做解释。
使用方法
注意:
在绑定生命周期的api中使用,需要主动removeCallBacks,防止内存泄漏。
结语
以上就是关于项目中一些固定线程的封装。
水平有限,如有不对之处,欢迎指出。
使用方法
注意:
在绑定生命周期的api中使用,需要主动removeCallBacks,防止内存泄漏。
结语
以上就是关于项目中一些固定线程的封装。
水平有限,如有不对之处,欢迎指出。
Android中关于项目中对Thread的管理(不是线程池)的更多相关文章
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...
- Android线程管理之ExecutorService线程池
前言: 上篇学习了线程Thread的使用,今天来学习一下线程池ExecutorService. 线程管理相关文章地址: Android线程管理之Thread使用总结 Android线程管理之Execu ...
- 通过Thread Pool Executor类解析线程池执行任务的核心流程
摘要:ThreadPoolExecutor是Java线程池中最核心的类之一,它能够保证线程池按照正常的业务逻辑执行任务,并通过原子方式更新线程池每个阶段的状态. 本文分享自华为云社区<[高并发] ...
- Android Studio 在项目中引用第三方jar包
在Android Studio项目中引用第三方jar包的方法: 步骤: 1.在build.gradle文件中添加如下代码: 备注:要添加在Android作用域下 sourceSets { main { ...
- android直接读取项目中的sqlite数据库
最近项目中要实现android读取sqlite数据库文件,在这里先做一个英汉字典的例子.主要是输入英语到数据库中查询相应的汉语意思,将其答案输出.数据库采用sqlite3. 如图: 实现过程完全是按照 ...
- Android Studio修改项目中整体包名
莫名的需求,要把之前的apk分成三个不同的apk,还要在应用市场能够上线,麻麻滴这样一听那还不要各个apk包的包名不同以及apk签名文件也不同嘛(签名文件一般也用不同,为防止上线冲突嘛).所以就亲自尝 ...
- ASP.NET中彩票项目中的计算复式投注的注数的方法
从别人做的项目中抽取出的代码:
- jfinal想用到中大型项目中的项目经验分享
jfinal 用在大项目中更加方便实用,节省无数的开发时间,代码量相对 SSH 减少 75% 至 90%,对于项目结构来说,简单提以下几点: 1:先分大模块,大模块内部可以根据划分的model分成子包 ...
- Eclipse 中 Java 项目中 .settings 文件夹作用
今天工作时,因对 .settings 文件夹误操作,耗时 6 个多小时,才了解到原因就出在 .settings 文件夹.经查阅资料,对 .settings 做如下整理: 就如setting这个名字,就 ...
随机推荐
- Linux基础入门学习笔记之二
第三节 用户及文件权限管理 Linux用户管理 Linux是可以实现多用户登录的操作系统 查看用户 who命令用于查看用户 shiyanlou是当前登录用户的用户名 pts/0中pts表示伪终端,后面 ...
- 关于《C++ Templates》
最近买了<C++ Templates>来看,书最开始部分阐述了关于此书的一些编程风格.本人感觉非常好,有些地方之前一直容易搞混,这里却讲述的很清楚.例如: 关于下面几种风格的代码: voi ...
- Django实战(18):提交订单
前面的内容已经基本上涵盖了Django开发的主要方面,我们从需求和界面设计出发,创建模型和修改模型,并通过scaffold作为开发的起点:在scaffold的基础上重新定制模板,并且通过Model类和 ...
- 黑马程序员_java基础笔记(10)...JDK1.5的新特性
—————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— 1:静态导入.2:for—each循环.3:自动装箱/拆箱.4:可变参数.5:枚举 ...
- slf4j logback pom
pom: <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding&g ...
- Spring Boot 教程demo
https://github.com/ityouknow/spring-boot-examples
- C# 中从网络上下载文件保存到本地文件
下面是C#中常用的从Internet上下载文件保存到本地的一些方法,没有太多的技巧. 1.通过 WebClient 类下载文件 WebClient webClient = new WebClien ...
- mysql 函数group_concat()
本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) .MySQL中group_concat函数完整的语法如下:group_c ...
- 牛客练习赛1 A - 矩阵
链接:https://www.nowcoder.com/acm/contest/2/A来源:牛客网 题目描述 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至 ...
- react篇章-React Props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变.这就是为什么有些容器组件需要定义 state 来更新和修改数据. 而子组件只能通过 pro ...