Android 异步加载深入解析

首先看下android异步加载的整体形式

    private class downLoadTask extends AsyncTask<String, Integer, String> {
        //这里是在后台执行任务,相当于开启了一个进程
        @Override
        protected String doInBackground(String... strings) {

            //在线程中将数据传输到UI主线程,也就是调用 这个方法
            publishProgress(1,2,3,4);
            return "下载完了";
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            //这里可动态的操作界面,就是说这里相当于一个handle处理器
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            //这里相当于在当前的下载完成时候调用这里
        }
    }

这么使用呢,也是非常简单的

new DownLoadTask().execute("下载地址");

其实最基本的也就是这样!接下来我们进一步讲解的深入一些

1,三个参数究竟是什么意思 String, Integer, String

doInBackground(String… strings),这里是异步加载执行需要传的参数也就是new DownLoadTask().execute(“下载地址”);中的下载地址。但是我们注意到了String后面是三个点,也就是说明,它接收的是一个数组,我们获取这个数组当然要通过角标来获取。例如这里我们就是strings[0],来获取下载地址。当然如果有多个地址就是string[1],string[2].

onProgressUpdate(Integer… values) 这个方法是上一个方法执行过程中传过来的值,这里是int类型的,当然也可以传多个值,这里也是数组,例如 publishProgress(1,2,3,4);(如上图), 当然接收的时候也跟上面的函数一样values[0], values[1]…….

onPostExecute(String s)这个是当本次加载执行完毕之后需要执行的函数,但是这里的参数又是从哪里来呢。其实这里是doInBackground(String… strings)的返回值。

说了这么多,亲爱的朋友们,你们知道这三个函数的意思了吗?

2, 从源码的角度解读AsyncTask

首先看谷歌工程师给我的一个例子

private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
 *     protected Long doInBackground(URL... urls) {
 *         int count = urls.length;
 *         long totalSize = 0;
 *         for (int i = 0; i < count; i++) {
 *             totalSize += Downloader.downloadFile(urls[i]);
 *             publishProgress((int) ((i / (float) count) * 100));
 *             // Escape early if cancel() is called
 *             if (isCancelled()) break;
 *         }
 *         return totalSize;
 *     }
 *
 *     protected void onProgressUpdate(Integer... progress) {
 *         setProgressPercent(progress[0]);
 *     }
 *
 *     protected void onPostExecute(Long result) {
 *         showDialog("Downloaded " + result + " bytes");
 *     }
 * }

3,源码对doInBackground的解释

    /**
     * Override this method to perform a computation on a background thread. The
     * specified parameters are the parameters passed to {@link #execute}
     * by the caller of this task.
     //通过调用publishProgress这个放来来更新UI界面(我添加的)
     * This method can call {@link #publishProgress} to publish updates
     * on the UI thread.
     *
     * @param params The parameters of the task.
     *
     * @return A result, defined by the subclass of this task.
     *
     * @see #onPreExecute()
     * @see #onPostExecute
     * @see #publishProgress
     */
    @WorkerThread
    protected abstract Result doInBackground(Params... params);

4,onPreExecute方法

这个方法我在上面没有添加,这个函数的功能表示在线程开始前做一些准备工作

    /**
     * Runs on the UI thread before {@link #doInBackground}.
     *
     * @see #onPostExecute
     * @see #doInBackground
     */
    @MainThread
    protected void onPreExecute() {
    }

5, onPostExecute

从源码的解释上来看, 这个函数是在doInBackground这个子线程执行完成后执行的,并且接受doInBackground的返回值
另外谷歌工程师也给们提醒了一下,这个方法在任务中断的时候不会被调用

    /**
     * <p>Runs on the UI thread after {@link #doInBackground}. The
     * specified result is the value returned by {@link #doInBackground}.</p>
     * 
     * <p>This method won't be invoked if the task was cancelled.</p>
     *
     * @param result The result of the operation computed by {@link #doInBackground}.
     *
     * @see #onPreExecute
     * @see #doInBackground
     * @see #onCancelled(Object) 
     */
    @SuppressWarnings({"UnusedDeclaration"})
    @MainThread
    protected void onPostExecute(Result result) {
    }

6,onProgressUpdate

源码说这个函数是在调用publishProgress函数之后执行的,并且接收传过来的数据

    /**
     * Runs on the UI thread after {@link #publishProgress} is invoked.
     * The specified values are the values passed to {@link #publishProgress}.
     *
     * @param values The values indicating progress.
     *
     * @see #publishProgress
     * @see #doInBackground
     */
    @SuppressWarnings({"UnusedDeclaration"})
    @MainThread
    protected void onProgressUpdate(Progress... values) {
    }

7,异步加载的handle

这里是AsyncTask的handle,通过handle来传递消息是结束还是传递进度信息

    private static class InternalHandler extends Handler {
        public InternalHandler(Looper looper) {
            super(looper);
        }

        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
        @Override
        public void handleMessage(Message msg) {
            AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    // There is only one result
                    result.mTask.finish(result.mData[0]);
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;
            }
        }
    }

根据上面的来看, android的异步加载也是基本handle来实现的,只是内部封装了,其实我们在使用的时候也只需要理解最上面的三个方法就已经够了

猜你喜欢

转载自blog.csdn.net/jeekmary/article/details/80701982