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

来源:互联网 发布:c语言静态局部变量 编辑:程序博客网 时间:2024/03/29 21:36
  • 引入:
    还是那个问题: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<String, Void, Bitmap>{        @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

<?xml version="1.0" encoding="utf-8"?><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);表示图片加载完成

运行结果:
这里写图片描述

代码来源:
iMooc网教程

0 0
原创粉丝点击