#多线程编程(一)

来源:互联网 发布:三大运营商哪个网络好 编辑:程序博客网 时间:2024/05/10 21:21

多线程编程(一)


在日常的android编程中,我们经常会遇到耗时操作,这时候如果我们不进行处理很容易引起应用程序的的ANR问题,不利于构建流畅的操作体验。
当你的android系统认为你的应用程序在合理时长时间内没有相应并关闭了这个应用程序,程序就会遭遇ANR事件,会给用户带来非常差的体验。
为了构建一个流畅运行的应用程序,包括诸如网络访问这样的耗时操作不应该阻塞主要的UI线程。

常见的阻碍线程的操作:

  • 所有过长或者过于复杂的计算和操作
  • 解析数据集(例如XML文件,JASON文件等)
  • 处理多媒体文件,例如图像,音频,视频
  • 对长度不定的数据结构进行迭代
  • 获取网络资源
  • 获取地理位置服务
  • 获取内容提供器接口
  • 接入本地数据库
  • 接入本地文件
    其中最常见的是网络访问的多线程处理!!此类操作必须从主线程中移除

对于多线程操作,android SDK提供了多种将操作从UI线程中移除的方法,最常见的有:
1.使用AsyncTask类,可以完成异步操作并保持与主线程的通信。
2.使用Thread类完成异步操作,并使用Handler类保持与主线程的通信。
3.具体实用类,AsyncQueryHandler的使用…..


AsyncTask详解与使用

AsyncTask为抽象类


An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.

AsyncTask类作为抽象类,使用时必须继承。对于异步任务有非常重要的3个参数,以及4个方法要继承
继承时可以为AsyncTask指定3个泛型参数

  1. Params 执行AsyncTask时需要传入参数,用于后台使用
  2. Progress 后台执行任务时,如果需要在前台显示当前进度,可以指定该泛型参数作为进度单位
  3. Result 异步任务执行完成后如果需要返回结果,可以指定该参数为返回值类型

    这里我们可以新建一个模拟网络下载继承类:
    DownLoadAsynctask类

并在其中复写重要的4个方法:

  1. onPreExecute() 后台任务执行前调用,在任务结束后立即调用用户界面线程调用。这一步通常用于设置任务,例如通过在用户界面显示一个进度条。
  2. doInBackground (Params… params) 异步任务的参数被传递到这一步,在子线程中运行,此处处理所有的耗时操作,可以在其中调用publishProgress(Progress…)进行实时数据的传递并在 onProgressUpdate (Progress… values)中对UI线程操作。
  3. onProgressUpdate (Progress… values) 后台调用了publishProgress(Progress…)后,该方法会很快被调用,接收到的参数可以对UI进行操作,利用参数值对UI进行实时的调整,以便展示后台要展示的数据,如进度等。
  4. onPostExecute(Result) 后台任务执行完成后被很快调用,Result参数表示onPoseExecute接收的参数 ,由doInBackground返回的参数。也可以进行UI操作,比如,提醒任务执行的结果,关闭UI中进度对话框等…..
//第一个参数表示doInBackground方法接收的参数//第二个参数表示onProgressUpdate接收的参数,publishProgress调用这个方法传递的参数//第三个参数表示onPoseExecute接收的参数 ,doInBackground返回的参数public class DownloadAsyncTask extends AsyncTask<String, Integer, String> {    TextView text;    ProgressBar pb;    //接收我们需要操作的ui组件    public DownloadAsyncTask(TextView text,ProgressBar pb) {        this.text = text;        this.pb=pb;    }    //在调用AsyncTask的execute()方法后这个方法在首先执行    @Override    protected void onPreExecute() {        text.setText("开始下载");    }    //这个方法在doInBackground执行完成之后执行这个方法    @Override    protected void onPostExecute(String result) {        text.setText(result);    }    //在publishProgress方法被调用时执行该方法    @Override    protected void onProgressUpdate(Integer... values) {        pb.setProgress(values[0]);        text.setText("开始下载:"+values[0]+"%");    }    //这个方法用来执行耗时操作,它是异步的,    //在它执行中需要调用publishProgress来向onProgressUpdate发送参数    @Override    protected String doInBackground(String... params) {        for (int i = 1; i <= 100; i++) {            AsyncTaskActivity.download();            this.publishProgress(i);//          pb.setProgress(i);//setProgress经过特殊处理,可以在多线程中更新进度//          text.setText("开始下载:"+i+"%");//textview不能直接在多线程中操作        }        return "从" + params[0] + " 下载完成。";    }}
0 0