Android中創(chuàng)建多線程管理器實(shí)例
如果你要反復(fù)執(zhí)行一個(gè)任務(wù),用不同的數(shù)據(jù)集(參數(shù)不同),但一次只要一個(gè)執(zhí)行(任務(wù)是單線程的),IntentService符合你的需求。當(dāng)需要在資源可用時(shí)自動(dòng)執(zhí)行任務(wù),或允許多任務(wù)同時(shí)執(zhí)行,你需要一個(gè)線程管理器管理你的線程。ThreadPoolExecutor,會(huì)維護(hù)一個(gè)隊(duì)列,當(dāng)它的線程池有空時(shí),從隊(duì)列里取任務(wù),并執(zhí)行。要運(yùn)行任務(wù),你要做的就是把它加到隊(duì)列里。
線程池可以并聯(lián)運(yùn)行一個(gè)任務(wù)的多個(gè)實(shí)例,所以你要保存代碼線程安全。能被多線程訪問的變量需要同步塊.更多信息,見Processes and Threads(http://developer.android.com/guide/components/processes-and-threads.html)
定義線程池類
在它自己類中實(shí)例ThreadPoolExecutor.在類里,如下操作:
為線程池使用static變量
你可能在app里只需要一個(gè)單例的線程池,這是為了統(tǒng)一控制限制CPU或網(wǎng)絡(luò)資源。如果你有不同的Runnable類型,你可能想要每種類型都有各自的線程池,但這些都可以放到一個(gè)單一的實(shí)例里。比如,你可以把它聲明成全局變量:
public class PhotoManager {
...
static {
...
// Creates a single static instance of PhotoManager
sInstance = new PhotoManager();
}
...
使用private構(gòu)造方法
把構(gòu)造方法聲明成private,可以確保單例,這意味著你不需要在同步代碼塊里封裝類訪問。
public class PhotoManager {
...
/**
* 構(gòu)建用來下載和decode圖片的工作隊(duì)列和線程池,因?yàn)闃?gòu)造方法標(biāo)記為private,
* 對其他類不可訪問(甚至同包下的類)
*/
private PhotoManager() {
...
}
調(diào)用線程池類里的方法來開始任務(wù)
線程池類里定義一個(gè)方法,用來添加任務(wù)到線程池隊(duì)列,如:
public class PhotoManager {
...
// 供PhotoView調(diào)用獲取圖片
static public PhotoTask startDownload(
PhotoView imageView,
boolean cacheFlag) {
...
// 添加一個(gè)任務(wù)到線程池
sInstance.
mDownloadThreadPool.
execute(downloadTask.getHTTPDownloadRunnable());
...
}
實(shí)例化一個(gè)UI線程的Handler.
Handler用于與UI線程通訊,大多數(shù)UI控件只允許在UI線程修改。
private PhotoManager() {
...
// Defines a Handler object that's attached to the UI thread
mHandler = new Handler(Looper.getMainLooper()) {
/*
* handleMessage() defines the operations to perform when
* the Handler receives a new Message to process.
*/
@Override
public void handleMessage(Message inputMessage) {
...
}
...
}
}
判斷線程池參數(shù)
一旦你有了全部類結(jié)構(gòu),你就可以開始定義線程池。實(shí)例化一個(gè)線程池對象,你需要下面的值:
初始池大小,最大池大小。
線程池的線程數(shù)量主要依賴于設(shè)備的CPU核心數(shù).可以從系統(tǒng)環(huán)境中獲取。
public class PhotoManager {
...
/*
* Gets the number of available cores
* (not always the same as the maximum number of cores)
*/
private static int NUMBER_OF_CORES =
Runtime.getRuntime().availableProcessors();
}
這個(gè)數(shù)字可能不能反映出設(shè)備的物理cpu內(nèi)核數(shù)量;某些設(shè)備CPU會(huì)根據(jù)系統(tǒng)負(fù)載自動(dòng)禁用部分內(nèi)核,對于這些設(shè)備,availableProcessors()返回的是當(dāng)前活躍的內(nèi)核數(shù)量。
保持活躍時(shí)間和時(shí)間單位
一個(gè)進(jìn)程在關(guān)閉前,保持空閑狀態(tài)的時(shí)間(可以復(fù)用進(jìn)程)。時(shí)間單位在TimeUnit里
任務(wù)隊(duì)列
ThreadPoolExecutor的列隊(duì)保存Runnable對象。在線程中執(zhí)行代碼,線程池管理器會(huì)從一個(gè)FIFO隊(duì)列里取出一個(gè)Runnable對象,附加到線程里。隊(duì)列實(shí)現(xiàn)BlockingQueue接口,在創(chuàng)建線程池時(shí)提供。你可以從現(xiàn)有實(shí)現(xiàn)中選一個(gè),適應(yīng)你的需求,參見ThreadPoolExecutor。下面是使用LinkedBlockingQueue的例子:
public class PhotoManager {
...
private PhotoManager() {
...
// A queue of Runnables
private final BlockingQueue<Runnable> mDecodeWorkQueue;
...
// Instantiates the queue of Runnables as a LinkedBlockingQueue
mDecodeWorkQueue = new LinkedBlockingQueue<Runnable>();
...
}
...
}
創(chuàng)建線程池
調(diào)用ThreadPoolExecutor()方法初始化線程池。它會(huì)創(chuàng)建管理線程。因?yàn)榫€程池的初始大小和最大池大小是一樣的,ThreadPoolExecutor在初始化時(shí)就創(chuàng)建了所有線程對象,如:
...
// Sets the amount of time an idle thread waits before terminating
private static final int KEEP_ALIVE_TIME = 1;
// Sets the Time Unit to seconds
private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
// Creates a thread pool manager
mDecodeThreadPool = new ThreadPoolExecutor(
NUMBER_OF_CORES, // Initial pool size
NUMBER_OF_CORES, // Max pool size
KEEP_ALIVE_TIME,
KEEP_ALIVE_TIME_UNIT,
mDecodeWorkQueue);
}
相關(guān)文章
非常詳細(xì)的android so庫逆向調(diào)試教程
這篇文章主要給大家介紹了關(guān)于android so庫逆向調(diào)試的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細(xì),對各位Android開發(fā)者具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-08-08Android?MaterialButton使用實(shí)例詳解(告別shape、selector)
我們平時(shí)寫布局,當(dāng)遇到按鈕需要圓角、或者描邊等,通常的方法是新建一個(gè)xml文件,在shape標(biāo)簽下寫,然后通過android:background或setBackground(drawable)設(shè)置,這篇文章主要給大家介紹了關(guān)于Android?MaterialButton使用詳解的相關(guān)資料,需要的朋友可以參考下2022-09-09Android開發(fā)之EditText框輸入清理工具類示例
這篇文章主要介紹了Android開發(fā)之EditText框輸入清理工具類,涉及Android事件監(jiān)聽及輸入框清理相關(guān)操作技巧,需要的朋友可以參考下2018-01-01詳解Android Webview加載網(wǎng)頁時(shí)發(fā)送HTTP頭信息
這篇文章主要介紹了詳解Android Webview加載網(wǎng)頁時(shí)發(fā)送HTTP頭信息的相關(guān)資料,需要的朋友可以參考下2017-05-05Android實(shí)現(xiàn)圖片拖動(dòng)效果
本文主要介紹了Android實(shí)現(xiàn)圖片拖動(dòng)效果的實(shí)例,具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-03-03android 簡單圖片動(dòng)畫播放的實(shí)例代碼
android 簡單圖片動(dòng)畫播放的實(shí)例代碼,需要的朋友可以參考一下2013-06-06android USB如何修改VID具體實(shí)現(xiàn)
在android 設(shè)備的Linux 內(nèi)核中把 USB 驅(qū)動(dòng)的 PID VID 修改以后,也許之前的adb工具就不能識(shí)別設(shè)備了,會(huì)打印出"device not found"的提示2013-06-06詳解Android通過修改配置文件設(shè)置wifi密碼
這篇文章主要介紹了詳解Android通過修改配置文件設(shè)置wifi密碼的相關(guān)資料,需要的朋友可以參考下2017-07-07