在上次博客中,我總結了一套比較實用的代碼框架,不知道有沒有幫助到你們?。。。(實用的代碼框架http://smallwoniu.blog.51cto.com/blog/3911954/1307060)核心思想是:一個線程(在Activity中開啓服務啓動線程的方式)來監聽處理任務隊列中tasks,來對其依次處理。java
細心地你們可能會發現要是任務在10個如下,框架還能夠承擔,要是任務過多時(主要是併發執行時),就會嫌的力不從心,從而影響整款軟件執行效率!android
/** * 線程不斷檢測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類併發
package com.zhf.android_frameworkdemo03.threadpool; public interface IActivity { /** * 初始化操做 */ public abstract void init(); /** * 刷新操做 * @param params 可變參數 */ public abstract void refresh(Object... params); }
TaskID類:app
package com.zhf.android_frameworkdemo03.model; public class TaskID { public static final int MANAGER_LOGIN = 0;// 管理員登陸 //以此類推,根據本身項目的需求添加任務ID }
TaskOperate類:框架
package com.zhf.android_frameworkdemo03.threadpool; /** * 任務操做接口 * @author ZHF * */ public interface TaskOperate { /** * 操做Task * @param Task Task實體 */ public abstract void operate(Task Task); }
接下來是重要的類
ide
ThreadPoolManager類:測試
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類:
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類:
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類:
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類:
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類:
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