在上次博客中,我总结了一套比较实用的代码框架,不知道有没有帮助到大家?。。。(实用的代码框架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,如需转载请自行联系原作者