Android笔记----AsyncTask异步消息处理机制

  • 引入:
    还是那个问题:Android的单线程模型原则只能在主线程更新UI.
    如果要在非主线程中更新UI,除了用Handler之外,还有一种封装得很好的机制AsyncTask
    源码解释: AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate(操作) threads and/or handlers.
    AsyncTask可以帮助我们在后台通过新线程执行操作并且把结果返回给UI线程.比起handlers它的封装性更高.

AsyncTask

参数引入:
  1. Params
    传入参数,给后台任务使用.比如我们要加载一个图片Url,则Params可以是String类型.
  2. Progress(进度)
    可以作为doInBackground执行的进度反映.
  3. Result
    任务执行完成,返回给主线程.

  • 使用:
    假如要执行耗时操作,例如加载一个网页图片或者登陆验证等
    Step 1. 我们可以新建一个类继承自AsyncTask
    Step 2. 重写AsyncTask的方法:
    1. onPreExecute()
      该方法用于耗时操作之前所做的准备,例如加载图片或者登陆操作之前显示进度条.
    2. doInBackground(Params…)
      该方法主要进行耗时操作,即启动新线程(已经自动封装)执行你要的操作.
      注意的是该方法常伴随着publishProgress(Progress…) 语句, 该方法可以调用并且传递参数Progress给第三个方法onProgressUpdate(Progress…)
    3. onProgressUpdate(Progress…) 根据publishProgress传递的参数获取当前耗时操作的进度.
    4. onPostExecute(Result)
      当耗时操作完成的时候,该方法会被调用,
      当你执行到这个方法的时候,此时已经处于UI线程了,此时可以放心的进行UI操作,其中Result作为返回结果,完全可以作为UI界面的更新.

简单代码示例:
我们通过一个小程序来测试AsyncTask的处理机制:
利用异步操作处理加载图片,在图片加载完成之后返回给UI线程并执行更新.

新建类ImageLoad继承自Activity
创建内部类MyAsyncTask 继承自AsyncTask

package com.example.asynctask_test;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

public class ImageLoad extends Activity {

    private ImageView imageView ;
    private ProgressBar progressbar;
    private static String url = 
            "http://img.mp.itc.cn/upload/20160320/3f7f53242afc44cb9e858ddb5a2334c9_th.jpg"; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image);
        imageView = (ImageView) findViewById(R.id.image);
        progressbar = (ProgressBar) findViewById(R.id.progressbar);
        //开启异步线程操作
        new MyAsyncTask().execute(url);
    }

    //内部类
    class MyAsyncTask extends AsyncTask{

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //线程开始之前,显示进度条(一直转圈)
            progressbar.setVisibility(View.VISIBLE);            
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            super.onPostExecute(result);
            //doInBackground完成之后执行根据返回的图片(result)更新UI
            //主线程
            progressbar.setVisibility(View.GONE);
            imageView.setImageBitmap(result); 

        }

        @Override
        protected Bitmap doInBackground(String... params ) {
            //取出参数作为URL
            String url = params[0];
            Bitmap bitmap = null;
            URLConnection connection;
            InputStream is; //由connection获取InputStream
            try {
                connection = new URL(url).openConnection();
                is = connection.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                //通过decodeStream解析输入流
                bitmap = BitmapFactory.decodeStream(bis);
                is.close();
                bis.close();
                //为了显示进度条,睡眠3秒
                Thread.sleep(3000);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //返回解析的Bitmap           
            return bitmap;          
        }       
    }   

}

ImageLoad布局文件 image.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <ImageView 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/image"/>

    <ProgressBar 
        android:id="@+id/progressbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:visibility="gone"
        />


RelativeLayout>

一开始我们把进度条设置为GONE(区别于invisible,GONE隐藏并且释放空间),当进入加载活动(doInbackground()执行之前)在onPreExecute()中进度条设置显示progressbar.setVisibility(View.VISIBLE);
在耗时操作完成后(图片加载完毕),在onPreExecute()执行progressbar.setVisibility(View.GONE);表示图片加载完成

运行结果:
Android笔记----AsyncTask异步消息处理机制_第1张图片

代码来源:
iMooc网教程

你可能感兴趣的:(Android)