【移动开发】Android应用程序中实用的代码框架(二)

在上次博客中,我总结了一套比较实用的代码框架,不知道有没有帮助到大家?【移动开发】Android应用程序中实用的代码框架(二)。。。(实用的代码框架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();
            }
        }
    }



鉴于实际开发中并发执行任务的情况较多!我整理了又一款非常实用的代码框架,也可以说是上次代码框架的加强版!

这次我采用了线程池的方式处理多任务,提高程序的运行效率。

【移动开发】Android应用程序中实用的代码框架(二)

首先是简单的一些类

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;
    }
}



到此,强大的代码框架已搭建起来,我们点击一下按钮,测试一下代码吧!

【移动开发】Android应用程序中实用的代码框架(二) ---------》【移动开发】Android应用程序中实用的代码框架(二)


为了让大家看的更清楚,我打印出了后台数据!

【移动开发】Android应用程序中实用的代码框架(二)

为了显示出框架的威力!我们可以试试狂点按钮,通过后台数据,我们知道了每次处理该任务是不同的线程!

【移动开发】Android应用程序中实用的代码框架(二)


框架代码源码下载地址:http://down.51cto.com/data/1011299






     本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1324842,如需转载请自行联系原作者





上一篇:纳德拉指出,机器学习能力将成为云计算的战场


下一篇:PostgreSQL 10.1 手册_前言_4. 进一步的信息