Libgdx学习笔记:分享自己写的异步加载

。_饼干妹妹 提交于 2019-12-03 09:37:17

从需求说起:

解析xml,json文件等耗时的操作,如果放到绘制线程,或者初始化里面,会导致画面卡顿一下,让人看起来不爽,这时候就想能不能异步加载一下。

查看Libgdx的AssetManager发现里面用到了AsyncExecutor,AsyncTask,AsyncResult相关异步线程池。

简单介绍下:

【AsyncExecutor】

在一个独立的线程里面,异步执行AsyncTask实例。不需要使用的时候,调用dispose()进行释放。

看内部源码,实际使用了java的线程池Executors.newFixedThreadPool来管理的。

简单说是处理AsyncTask的容器。

AsyncTask】为接口,可根据实际情况实现成自己的Task。

提交任务给一个AsyncExecutor,返回类型为T的结果。

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

}



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!