Libgdx學習筆記:分享本身寫的異步加載

從需求提及:
java

解析xml,json文件等耗時的操做,若是放到繪製線程,或者初始化裏面,會致使畫面卡頓一下,讓人看起來不爽,這時候就想能不能異步加載一下。json

查看Libgdx的AssetManager發現裏面用到了AsyncExecutor,AsyncTask,AsyncResult相關異步線程池。異步

簡單介紹下:async

【AsyncExecutor】ide

在一個獨立的線程裏面,異步執行AsyncTask實例。不須要使用的時候,調用dispose()進行釋放。this

看內部源碼,實際使用了java的線程池Executors.newFixedThreadPool來管理的。spa

簡單說是處理AsyncTask的容器。線程

AsyncTask】爲接口,可根據實際狀況實現成本身的Task。code

提交任務給一個AsyncExecutor,返回類型爲T的結果。xml

【AsyncResult】

 AsyncExecutor.submit(AsyncTask)返回的結果。

 isDone()方法,表明任務是否處理完畢。

=================================================================

上代碼:

CHAsyncTask 抽象任務類

CHAsyncManager異步管理中心,最好放在Game裏面初始化一次,而且在render()中調用update()方法。

經過循環的檢測AsyncResult,來查看異步任務是否被執行完畢。

簡單說:咱們到蛋糕店,訂了一塊蛋糕,老闆給了你一個提貨單,而後讓後廚加緊作蛋糕,這時,你讓小明每隔半小時拿着提貨單到蛋糕店去查看,蛋糕作好了嗎。若是作好了,你就拿回來。

這個期間你徹底能夠去作其餘事情,而沒必要一直在等待。

作蛋糕=》CHAsyncTask 

提貨單=》AsyncResult

小明=》Game中的render()




public abstract class CHAsyncTask implements AsyncTask<String> {
    private CHAsyncManager asyncManager;
    // 處理結果
    private AsyncResult<String> depsFuture = null;

    // 處理OK?
    volatile boolean asyncDone = false;

    public CHAsyncTask() {

    }

    public CHAsyncTask(CHAsyncManager manager) {
        asyncManager = manager;
    }

    @Override
    public String call() throws Exception {
        // 執行任務
        String result = doInBackground();
        asyncDone = true;
        return result;
    }

    /**開始執行*/
    public abstract void onPreExecute();

    /**執行結束返回結果*/
    public abstract void onPostExecute(String result);

    /**異步執行*/
    public abstract String doInBackground();

    // 
    public boolean update() {
        if (!asyncDone) {
        //沒有執行完成
            if (depsFuture == null) {
                // 也沒有提交任務,進行提交
                onPreExecute();
                depsFuture = asyncManager.getExecutor().submit(this);
            }
        } else {
            if (depsFuture.isDone()) {
            // 經過結果發現執行完畢了
                try {
                    onPostExecute(depsFuture.get());
                } catch (Exception e) {
                    throw new GdxRuntimeException("depsFuture.get() failed!!!!");
                }

            }
        }

        return asyncDone;
    }

    public void setAsyncManager(CHAsyncManager asyncManager) {
        this.asyncManager = asyncManager;
    }

    public CHAsyncManager getAsyncManager() {
        return asyncManager;
    }

    /**
     * 
     * <pre>
     * 是否執行完畢
     * 
     * date: 2015-1-18
     * </pre>
     * @author 
     * @return
     */
    public boolean isDone() {
        return asyncDone;
    }
}
public class CHAsyncManager implements Disposable {
    // 任務堆棧
    private final Stack<CHAsyncTask> tasks = new Stack<CHAsyncTask>();

    private AsyncExecutor executor;

    public CHAsyncManager() {
        // 池中容許的最大線程數1。超過最大上限會等待前面的執行完才接着執行。
        executor = new AsyncExecutor(1);
    }

    public boolean update() {
        if (tasks.size() == 0)
            return true;

        return updateTask() && tasks.size() == 0;
    }

    private boolean updateTask() {
        //任務更新狀況
        CHAsyncTask task = tasks.peek();
        if (task.update()) {
            // 處理完畢了,移除掉
            tasks.pop();
            return true;
        }
        return false;
    }

    /**
    *預先加載任務
    */
    public void loadTask(CHAsyncTask task) {
        if (task.getAsyncManager() == null) {
            task.setAsyncManager(this);
        }
        tasks.push(task);
    }

    @Override
    public void dispose() {
        executor.dispose();
    }

    public AsyncExecutor getExecutor() {
        return executor;
    }

}
相關文章
相關標籤/搜索