AsyncTask的用法

在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则:
1. 不要阻塞UI线程
2. 确保只在UI线程中访问Android UI工具包
      当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。
      比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText()的.因为其他线程中是不能直接访问主UI线程成员 。

android提供了几种在其他线程中访问UI线程的方法。
Activity.runOnUiThread( Runnable )
View.post( Runnable )
View.postDelayed( Runnable, long )
Hanlder
这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。
     为了解决这个问题,Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。相对来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现。
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String。
     AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
1) 子类化AsyncTask
2) 实现AsyncTask中定义的下面一个或几个方法
    onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
   doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
   onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
   onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
      doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为 doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。

从网上获取一个网页,在一个TextView中将其源代码显示出来

package test.list;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class NetworkActivity extends Activity{
private TextView message;
private Button open;
private EditText url;
    @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
       setContentView(R.layout.network);
       message= (TextView) findViewById(R.id.message);
       url= (EditText) findViewById(R.id.url);
       open= (Button) findViewById(R.id.open);
       open.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
              connect();
           }
       });
    }
private void connect() {
        PageTask task = new PageTask(this);
        task.execute(url.getText().toString());
    }
class PageTask extends AsyncTask<String, Integer, String> {
// 可变长的输入参数,与AsyncTask.exucute()对应
        ProgressDialog pdialog;
public PageTask(Context context){
            pdialog = new ProgressDialog(context, 0);   
            pdialog.setButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int i) {
              dialog.cancel();
             }
            });
            pdialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
              finish();
             }
            });
            pdialog.setCancelable(true);
            pdialog.setMax(100);
            pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            pdialog.show();
        }
        @Override
protected String doInBackground(String... params) {
try{
               HttpClient client = new DefaultHttpClient();
// params[0]代表连接的url
               HttpGet get = new HttpGet(params[0]);
               HttpResponse response = client.execute(get);
               HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
               InputStream is = entity.getContent();
               String s = null;
if(is != null) {
                   ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int ch = -1;
int count = 0;
while((ch = is.read(buf)) != -1) {
                      baos.write(buf, 0, ch);
                      count += ch;
if(length > 0) {
// 如果知道响应的长度,调用publishProgress()更新进度
                          publishProgress((int) ((count / (float) length) * 100));
                      }
// 让线程休眠100ms
                      Thread.sleep(100);
                   }
                   s = new String(baos.toByteArray());              }
// 返回结果
return s;
            } catch(Exception e) {
               e.printStackTrace();
            }
return null;
        }
        @Override
protected void onCancelled() {
super.onCancelled();
        }
        @Override
protected void onPostExecute(String result) {
// 返回HTML页面的内容
            message.setText(result);
            pdialog.dismiss(); 
        }
        @Override
protected void onPreExecute() {
// 任务启动,可以在这里显示一个对话框,这里简单处理
            message.setText(R.string.task_started);
        }
        @Override
protected void onProgressUpdate(Integer... values) {
// 更新进度
              System.out.println(""+values[0]);
              message.setText(""+values[0]);
              pdialog.setProgress(values[0]);
        }
     }
}

最后需要说明AsyncTask不能完全取代线程,在一些逻辑较为复杂或者需要在后台反复执行的逻辑就可能需要线程来实现了。

 

原文地址:  http://www.cnblogs.com/dawei/archive/2011/04/18/2019903.html

转载于:https://www.cnblogs.com/yangzhenyu/archive/2011/10/08/2201777.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

突破select的FD_SETSIZE限制

前言&#xff1a; 在很多比较各种网络模型的文章中&#xff0c;但凡提到select模型时&#xff0c;都会说select受限于轮询的套接字数量&#xff0c;这个 数量也就是系统头文件中定义的FD_SETSIZE值(例如64)。但事实上这个算不上真的限制。 C语言的偏方&#xff1a; 在C语…

袋装树和随机森林的区别

装袋法建树的时候是将所有预测变量都考虑进去&#xff0c; 而随机森林则是考虑每一个分裂点时&#xff0c;都是从所有的预测变量p中随机选取m个预测变量&#xff0c;分裂点所用的预测变量只能从这m个变量中选择。

如何导入maven源文件_如何正确导入maven项目到eclipse?

Eclipse不允许一个项目被导入不止一次,在您的情况下,来自中继线和分支.This article显示了如何通过自定义maven配置文件绕过此限制.基本上,步骤是&#xff1a;>将以下配置文件添加到您的父pom.xml中append-to-project-nameappend.to.project.namemaven-eclipse-plugin[artif…

画廊效果

http://www.no3dfx.com/polaroid/ 转载于:https://www.cnblogs.com/bearhb/archive/2011/10/12/2208162.html

python镜像

Python国内镜像地址&#xff1a; 1.阿里云&#xff1a;https://mirrors.aliyun.com/pypi/simple/ 2.豆瓣&#xff1a;https://pypi.douban.com/simple/ 3.清华大学&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple/ 4.中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/…

socket 编程入门教程(一)TCP server 端:3、sockaddr与sockaddr_in

收件人地址一家化妆品公司将一批新产品的样品&#xff0c;准备发给某学校某个班的女生们免费试用。通常情况下&#xff0c;这件邮包的地址上可以这么写&#xff1a;收件人&#xff1a;全体女生。 地址&#xff1a;A省B市C学校&#xff0c;X级Y班。但是&#xff0c;如果在描述地…

python语言为什么叫python_Python为什么叫Python,Java又如何而来?

你可能听过这样一种说法&#xff1a;在计算机科学领域&#xff0c;只有两件困难的事情&#xff0c;其中一件是给事物命名。有些编程语言的名字很有意义&#xff0c;比如谷歌(Google)将它的编程语言命名为Go(lang)&#xff0c;而其他的名字——比如Python和Java——为什么要这么…

arcgis中的SetNull(,)函数使用

SetNull(设置条件&#xff0c;将条件之内的值变为nodata,条件之外的值处理) 例如&#xff1a; 1.setnull("DEM"500,"DEM"),将DEM中值为500的数据赋为空&#xff0c;其他保留原值 2.setnull("DEM">500,"DEM"),将DEM中值大于500的…

pyqt5设置dialog的标题_PyQt5快速上手基础篇7-弹出dialog

前言本节我们学习QDialog的使用&#xff0c;在主页面点击按钮弹出一个新的Dialog。一、基础知识1. dialog简介窗口是GUI设计中不可获取的一部分&#xff0c;方便用户和程序直接交互&#xff0c;简化使用&#xff1b;Qdialog主要包含QInputDialog、QColorDialog、QFontDialog、Q…

67、ulimit的使用

1、ulimit set or get the shells resource usage limits ulimit [OPTIONS] [LIMIT] 2、option ① -a 显示当前所有的资源限制。 ② -c size:设置core文件的最大值。单位:blocks ③ -n size 指定同一时间最多可开启的文件数 ④ -l size:设置在内存中锁定进程的最大值。单位:KB…

如何处理MODIS蒸散数据(ET)中的填充值(仅作参考)

该处理过程是个人想法&#xff0c;仅做参考&#xff0c;如果想要等到比精确的蒸散数据请参考《京津唐地区城市扩张对地表蒸散发的影响》中蒸散的计算过程。 MOD16A3 第 6 版蒸发蒸腾/潜热通量产品是按 500 米 (m) 像素分辨率生成的年度复合数据集。 根据《京津唐地区城市扩张对…

winform定义数据源名称_winform ComboBox自定义数据源实现用户输入时出现与用户输入匹配的项...

ComboBox自定义数据源实现用户输入时出现与用户输入匹配的项using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace _2012_11_15Pra…

如何计算栅格有效值范围内的统计值(最大值,最小值,平均值,方差)

大致思路&#xff1a; 1.将无效值设置为空(nodata) 2.对栅格进行计算 使用数据为&#xff1a;modis的蒸散数据&#xff08;有效值范围为0 至 65500&#xff0c;填充值范围为65529 至 65535&#xff09; 步骤 1&#xff0c;利用栅格计算器将填充值进行设置为空 结果 2计算栅…

RMAN 备份报错 RMAN-06207 RMAN-06208 解决方法

新搭建的环境&#xff0c;还没上线&#xff0c;今天在部署脚本&#xff0c;RMAN 备份中有一个警告&#xff0c;内容如下&#xff1a;RMAN-06207: WARNING: 1 objects could not bedeleted for DISK channel(s) dueRMAN-06208: to mismatched status. Use CROSSCHECK …

用python画明星_用python画一只可爱的皮卡丘实例

效果图片# !\/usr\/bin\/env python # - * -编码:utf - 8 - *\u2014\u2014从龟进口*\u201C画皮卡丘的头\u201Cdef的脸(x, y):\u201D\u201C画脸\u201D\u201Cbegin_fill () penup () # goto乌龟移动到指定的坐标(x, y) pendown() #设置的方向龟setheading(40)圆(-150、69)fillcol…

socket 编程入门教程(一)TCP server 端:1、建模

绝大部分关于socket编程的教程总是从socket的概念开始讲起的。要知道&#xff0c;socket的初衷是个庞大的体系&#xff0c;TCP/IP只是这个庞大体系下一个很小的子集&#xff0c;而我们真正能用上的更是这个子集中的一小部分&#xff1a;运输层&#xff08;Host-to-Host Transpo…

socket 编程入门教程(一)TCP server 端:2、socket与文件描述符

UNIX中的一切事物都是文件&#xff08; everything in Unix is a file!&#xff09;当我在这篇教程中提到UNIX的时候&#xff0c;其意思专指符合UNIX标准的所谓“正统”UNIX的衍生系统&#xff08;其实我就用来带指那些买了最初UNIX源代码的商业系统&#xff09;操作系统和类似…

linux 故障注入_用软件中断实现的Linux内核故障注入方法

用软件中断实现的Linux内核故障注入方法郭庆伟;杨麦顺;张影;张兴军【期刊名称】《计算机应用》【年(卷),期】2014(000)0z2【摘要】针对容错操作系统的可靠性评测问题&#xff0c;提出一种向Linux内核注入“单个位”故障的方法。基于x86体系结构中的软件中断机制&#xff0c;首先…

arcgis将一个字段里的文字按上下标进行显示

示例 代码如下 def FindLabel ( [分区代号] ):a [分区代号]ba[0:1]<sub>a[1:2]</sub>return b