在上次博客中,我总结了一套比较实用的代码框架,不知道有没有帮助到大家?。。。(实用的代码框架http://smallwoniu.blog.51cto.com/blog/3911954/1307060)核心思想是:一个线程(在Activity中开启服务启动线程的方式)来监听处理任务队列中tasks,来对其依次处理。
细心地大家可能会发现要是任务在10个以下,框架还可以承担,要是任务过多时(主要是并发执行时),就会嫌的力不从心,从而影响整款软件执行效率!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/**
* 线程不断检测tasks中的任务
*/
@Override
public
void
run() {
while
(isRun) {
Task task =
null
;
if
(!tasks.isEmpty()) {
task = tasks.poll();
if
(
null
!= task) {
doTask(task);
//处理任务
}
}
try
{
Thread.sleep(
1000
);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
|
鉴于实际开发中并发执行任务的情况较多!我整理了又一款非常实用的代码框架,也可以说是上次代码框架的加强版!
这次我采用了线程池的方式处理多任务,提高程序的运行效率。
首先是简单的一些类
IActivity类
1
2
3
4
5
6
7
8
9
10
11
12
|
package
com.zhf.android_frameworkdemo03.threadpool;
public
interface
IActivity {
/**
* 初始化操作
*/
public
abstract
void
init();
/**
* 刷新操作
* @param params 可变参数
*/
public
abstract
void
refresh(
Object
... params);
}
|
TaskID类:
1
2
3
4
5
6
7
|
package
com.zhf.android_frameworkdemo03.model;
public
class
TaskID {
public
static
final
int
MANAGER_LOGIN =
0
;
// 管理员登录
//以此类推,根据自己项目的需求添加任务ID
}
|
TaskOperate类:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package
com.zhf.android_frameworkdemo03.threadpool;
/**
* 任务操作接口
* @author ZHF
*
*/
public
interface
TaskOperate {
/**
* 操作Task
* @param Task Task实体
*/
public
abstract
void
operate(Task Task);
}
|
接下来是重要的类
ThreadPoolManager类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
package
com.zhf.android_frameworkdemo03.threadpool;
import
java.util.Collections;
import
java.util.LinkedList;
import
java.util.List;
import
android.util.Log;
/**
* 线程池管理器
* @author ZHF
*
*/
public
class
ThreadPoolManager {
public
static
String TAG =
"ThreadPoolManager"
;
public
static
ThreadPoolManager instance =
null
;
//Returns a wrapper on the specified List which synchronizes all access to the List.
public
static
List<Task> taskQueue = Collections.synchronizedList(
new
LinkedList());
//任务队列(LinkedList:便于插入和删除)
private
WorkThread[] workQueue;
//运行的线程数组
private
static
int
threadNumber =
5
;
//线程池数量5
/**构造方法(单例)**/
private
ThreadPoolManager(TaskOperate taskOperate) {
this
(threadNumber, taskOperate);
}
/**构造方法(单例):实例化线程数组**/
private
ThreadPoolManager(
int
threadNumber, TaskOperate taskOperate) {
this
.threadNumber = threadNumber;
this
.workQueue =
new
WorkThread[threadNumber];
//装线程数组
for
(
int
i =
0
; i < threadNumber; i++) {
this
.workQueue[i] =
new
WorkThread(i, taskOperate);
//将线程对应装入数组
System.out.println(
"当前运行的是"
+ i +
"个线程"
);
}
}
/**获取该类的实例对象(懒汉式)**/
public
static
synchronized
ThreadPoolManager getInstance(TaskOperate taskOperate) {
if
(instance ==
null
) {
instance =
new
ThreadPoolManager(taskOperate);
return
instance;
//获取实例
}
return
null
;
}
/**添加单个任务**/
public
void
addTask(Task task) {
synchronized
(taskQueue) {
//锁住线程队列对象
if
(task !=
null
) {
taskQueue.add(task);
taskQueue.notifyAll();
System.out.println(
"任务: "
+ task.getTaskInfo() +
"--添加成功--"
);
}
}
}
/**添加多个任务**/
public
void
addTasks(Task[] tasks) {
synchronized
(taskQueue) {
//锁住线程队列对象
for
(Task t : tasks) {
//遍历
if
(tasks !=
null
) {
taskQueue.add(t);
taskQueue.notifyAll();
System.out.println(
"任务: "
+ t.getTaskInfo() +
"--添加成功--"
);
}
}
}
}
/**销毁线程**/
public
void
destroy() {
Log.i(TAG,
"线程池管理器destroy方法开始。。。"
);
for
(
int
i =
0
; i < threadNumber; i++) {
this
.workQueue[i].stopThread();
//停止线程
this
.workQueue[i] =
null
;
//GC回收
}
synchronized
(taskQueue) {
//锁住线程队列对象
//清空队列集合
taskQueue.clear();
}
Log.i(TAG,
"线程池管理器destroy方法结束。。。"
);
System.gc();
//内存回收
}
}
|
说明:
1.这里我并没有使用ThreadPoolExecutor来真正的实现线程池操作,而是用数组装载线程的方式模拟线程池操作,在实例化该类的时候(程序启动时)我们开启了5个WorkThread在后台等待执行任务。
2.该类还有两个重要的方法:
addTask()---->添加具体任务到任务队列
destroy() ---->销毁线程
WorkThread类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
package
com.zhf.android_frameworkdemo03.threadpool;
import
android.util.Log;
/**
* 工作线程
* @author ZHF
*
*/
public
class
WorkThread
extends
Thread {
private
int
taskId;
//任务Id
private
boolean
isRunning =
true
;
//线程启动标记
private
TaskOperate taskOperate;
//任务操作接口
/**构造方法:启动线程**/
public
WorkThread(
int
taskId, TaskOperate taskOperate) {
this
.taskId = taskId;
this
.taskOperate = taskOperate;
//启动
this
.start();
}
@Override
public
void
run() {
while
(isRunning) {
Task task =
null
;
synchronized
(ThreadPoolManager.taskQueue) {
//线程队列
//线程虽然开启,但是没有任务队列中没有添加具体任务进来
while
(isRunning && ThreadPoolManager.taskQueue.isEmpty()) {
try
{
ThreadPoolManager.taskQueue.wait(20L);
}
catch
(InterruptedException e) {
System.out.println(
"线程"
+
this
.taskId +
"在运行时,报InterruptedException"
);
Log.e(ThreadPoolManager.TAG,
"线程"
+
this
.taskId +
"在运行时,报InterruptedException"
);
e.printStackTrace();
}
}
if
(
this
.isRunning) {
//移除任务
task = ThreadPoolManager.taskQueue.remove(
0
);
}
}
//有任务进来
if
(task !=
null
) {
System.out.println(task.getTaskInfo() +
"任务在线程"
+
this
.taskId +
"中开始。。。"
);
//处理任务(调用接口中方法处理,具体实现在子类当中。多态)
this
.taskOperate.operate(task);
System.out.println(task.getTaskInfo() +
"任务在线程"
+
this
.taskId +
"结束中。。。"
);
}
}
}
/**停止线程**/
public
void
stopThread() {
this
.isRunning =
false
;
}
}
|
说明:
该类是一个线程类,主要用于处理任务队列中任务事件,5个线程共同处理任务集合中的task,避免了先前一个线程处理task时,后一个task等待的情况,提高了系统的执行效率!
ClientTask类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
package
com.zhf.android_frameworkdemo03.services;
import
android.os.Handler;
import
android.os.Message;
import
com.zhf.android_frameworkdemo03.MyApplication;
import
com.zhf.android_frameworkdemo03.handle.LoginHandler;
import
com.zhf.android_frameworkdemo03.model.TaskID;
import
com.zhf.android_frameworkdemo03.threadpool.IActivity;
import
com.zhf.android_frameworkdemo03.threadpool.Task;
import
com.zhf.android_frameworkdemo03.threadpool.TaskOperate;
/**
* 统一处理任务类
* @author ZHF
*
*/
public
class
ClientTask
implements
TaskOperate{
/**统一任务处理**/
@Override
public
void
operate(Task task) {
Message message = mHandler.obtainMessage();
message.what = task.getId();
//1.根据TaskID来判断,调用对应的XXhandler来处理任务
//2.处理完成得到返回的message.obj数据,将其统一sendMessage(message)出去
//3.在消息处理机制mHandler中对应接收数据,刷新对应的UI界面
switch
(task.getId()) {
case
TaskID.MANAGER_LOGIN:
//管理员登陆
//处理登录事件,获取message.obj数据
LoginHandler.getLogin(task, message);
break
;
//此处添加后续任务
}
mHandler.sendMessage(message);
//发送消息
}
/**消息处理**/
public
Handler mHandler =
new
Handler() {
@Override
public
void
handleMessage(Message msg) {
super
.handleMessage(msg);
IActivity ia =
null
;
//根据传来的任务消息ID,来对应的传递参数刷新界面
switch
(msg.what) {
case
TaskID.MANAGER_LOGIN:
//管理员登陆
ia = MyApplication.getActivityByName(
"MainActivity"
);
ia.refresh(msg.obj);
break
;
//此处添加后续任务
}
}
};
}
|
说明:
1.该类实现了先前定义的TaskOperate接口,重写了operate()处理任务,对应TaskID我们新建了一个类LoginHandler来处理,最后接收处理结果message.obj,并统一发送到mHandler接收,刷新对应的UI界面。
2.注意:该类我们实现的是客户端的一系列请求任务,当然我们还可以再定义一个类,实现TaskOperate接口,用于统一操作服务器端Task,也是可以的,扩展么!)
LoginHandler类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package
com.zhf.android_frameworkdemo03.handle;
import
com.zhf.android_frameworkdemo03.threadpool.Task;
import
android.os.Message;
/**
* 登录事件处理
* @author ZHF
*
*/
public
class
LoginHandler {
/**处理登录事物,将结果用消息发送出去**/
public
static
void
getLogin(Task task, Message message) {
//处理完成。。。。
message.obj =
"登陆成功!"
;
}
}
|
程序入口
MainActivity类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
package
com.zhf.android_frameworkdemo03;
import
com.zhf.android_frameworkdemo03.model.TaskID;
import
com.zhf.android_frameworkdemo03.threadpool.IActivity;
import
com.zhf.android_frameworkdemo03.threadpool.Task;
import
android.os.Bundle;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
import
android.widget.TextView;
import
android.app.Activity;
public
class
MainActivity
extends
Activity
implements
IActivity{
public
Button mBtnLogin;
//登陆按钮:测试代码框架是否运行正常
public
TextView mTvLogin;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.将要执行任务的Activity,加入到集合中
MyApplication.allActivity.add(
this
);
this
.mBtnLogin = (Button) findViewById(R.id.button1);
this
.mTvLogin = (TextView) findViewById(R.id.textView1);
mBtnLogin.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
//2.产生任务:对应填入参数
Task task =
new
Task(TaskID.MANAGER_LOGIN,
"框架测试成功!!"
,
"---登陆任务----"
);
//3.将当前任务加入到写好的线程池中()
MyApplication.poolManager.addTask(task);
}
});
}
@Override
public
void
init() {
// TODO Auto-generated method stub
}
@Override
public
void
refresh(Object... params) {
//接收线程处理过后返回的数据
mTvLogin.setText(params[
0
].toString());
}
}
|
MyApplication类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
package
com.zhf.android_frameworkdemo03;
import
java.util.ArrayList;
import
com.zhf.android_frameworkdemo03.services.ClientTask;
import
com.zhf.android_frameworkdemo03.threadpool.IActivity;
import
com.zhf.android_frameworkdemo03.threadpool.ThreadPoolManager;
import
android.app.Application;
/**
*加载配置文件,监测网络情况,初始化任务线程池
* @author ZHF
*
*/
public
class
MyApplication
extends
Application{
// 所有实现接口IActivity的Activity,即放置所有要执行任务的Activity
public
static
ArrayList<IActivity> allActivity =
new
ArrayList<IActivity>();
public
static
ThreadPoolManager poolManager;
/**程序启动**/
@Override
public
void
onCreate() {
super
.onCreate();
//程序启动时,开启线程池(5个线程,等待task)
poolManager = ThreadPoolManager.getInstance(
new
ClientTask());
}
/**根据名字获取Activity**/
public
static
IActivity getActivityByName(
String
name) {
IActivity ia =
null
;
for
(IActivity ac : allActivity) {
if
(ac.getClass().getName().endsWith(name)) {
ia = ac;
}
}
return
ia;
}
}
|
到此,强大的代码框架已搭建起来,我们点击一下按钮,测试一下代码吧!
为了让大家看的更清楚,我打印出了后台数据!

为了显示出框架的威力!我们可以试试狂点按钮,通过后台数据,我们知道了每次处理该任务是不同的线程!
框架代码源码下载地址:http://down.51cto.com/data/1011299
本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1324842,如需转载请自行联系原作者