Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android中創建多線程管理器實例

Android中創建多線程管理器實例

編輯:Android開發實例

如果你要反復執行一個任務,用不同的數據集(參數不同),但一次只要一個執行(任務是單線程的),IntentService符合你的需求。當需要在資源可用時自動執行任務,或允許多任務同時執行,你需要一個線程管理器管理你的線程。ThreadPoolExecutor,會維護一個隊列,當它的線程池有空時,從隊列裡取任務,並執行。要運行任務,你要做的就是把它加到隊列裡。

線程池可以並聯運行一個任務的多個實例,所以你要保存代碼線程安全。能被多線程訪問的變量需要同步塊.更多信息,見Processes and Threads(http://developer.android.com/guide/components/processes-and-threads.html)

定義線程池類

在它自己類中實例ThreadPoolExecutor.在類裡,如下操作:

為線程池使用static變量

你可能在app裡只需要一個單例的線程池,這是為了統一控制限制CPU或網絡資源。如果你有不同的Runnable類型,你可能想要每種類型都有各自的線程池,但這些都可以放到一個單一的實例裡。比如,你可以把它聲明成全局變量:
代碼如下:

public class PhotoManager {
    ...
    static  {
        ...
        // Creates a single static instance of PhotoManager
        sInstance = new PhotoManager();
    }
    ...

使用private構造方法

把構造方法聲明成private,可以確保單例,這意味著你不需要在同步代碼塊裡封裝類訪問。
代碼如下:

 public class PhotoManager {
        ...
        /**
         * 構建用來下載和decode圖片的工作隊列和線程池,因為構造方法標記為private,
         * 對其他類不可訪問(甚至同包下的類)
         */
        private PhotoManager() {
            ...
        }

調用線程池類裡的方法來開始任務

線程池類裡定義一個方法,用來添加任務到線程池隊列,如:
代碼如下:

public class PhotoManager {
    ...
    // 供PhotoView調用獲取圖片
    static public PhotoTask startDownload(
        PhotoView imageView,
        boolean cacheFlag) {
        ...
        // 添加一個任務到線程池
        sInstance.
                mDownloadThreadPool.
                execute(downloadTask.getHTTPDownloadRunnable());
        ...
    }

實例化一個UI線程的Handler.

Handler用於與UI線程通訊,大多數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) {
                ...
            }
        ...
        }
    }

判斷線程池參數

一旦你有了全部類結構,你就可以開始定義線程池。實例化一個線程池對象,你需要下面的值:
初始池大小,最大池大小。
線程池的線程數量主要依賴於設備的CPU核心數.可以從系統環境中獲取。

代碼如下:

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

這個數字可能不能反映出設備的物理cpu內核數量;某些設備CPU會根據系統負載自動禁用部分內核,對於這些設備,availableProcessors()返回的是當前活躍的內核數量。

保持活躍時間和時間單位

一個進程在關閉前,保持空閒狀態的時間(可以復用進程)。時間單位在TimeUnit裡

任務隊列

ThreadPoolExecutor的列隊保存Runnable對象。在線程中執行代碼,線程池管理器會從一個FIFO隊列裡取出一個Runnable對象,附加到線程裡。隊列實現BlockingQueue接口,在創建線程池時提供。你可以從現有實現中選一個,適應你的需求,參見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>();
        ...
    }
    ...
}

創建線程池

調用ThreadPoolExecutor()方法初始化線程池。它會創建管理線程。因為線程池的初始大小和最大池大小是一樣的,ThreadPoolExecutor在初始化時就創建了所有線程對象,如:

代碼如下:
    private PhotoManager() {
        ...
        // 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);
    }

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved