在开发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中将其源代码显示出来
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用法的更多相关文章

  1. [转载]ssget 用法详解 by yxp

    总结得很好的ssget用法.....如此好文,必须转载. 原文地址: http://blog.csdn.net/yxp_xa/article/details/72229202 ssget 用法详解 b ...

  2. AsyncTask用法解析-下载文件动态更新进度条

    1. 泛型 AysncTask<Params, Progress, Result> Params:启动任务时传入的参数,通过调用asyncTask.execute(param)方法传入. ...

  3. Handler, AsyncTask用法简单示例

    package com.jim.testapp; import android.app.Activity; import android.os.AsyncTask; import android.os ...

  4. [转载]Vector用法(C++ Primer中文版)

    转自:http://blog.sciencenet.cn/blog-261330-551086.html vector 是同一种类型的对象的集合,每个对象都有一个对应的整数索引值.和 string 对 ...

  5. [转载]dbms_lob用法小结

    http://blog.sina.com.cn/s/blog_713978a50100prkt.html CLOB里存的是2进制 判定长度   DBMS_LOB.GETLENGTH(col1)获取文本 ...

  6. 转载 HashSet用法

    NET 3.5在System.Collections.Generic命名空间中包含一个新的集合类:HashSet<T>.这个集合类包含不重复项的无序列表.这种集合称为“集(set)”.集是 ...

  7. 转载 | embed用法(网站中视频、音频的添加)

    网站中添加视频: <embed src="http://player.video.qiyi.com/390cf6c74450e4c70b7bd2d883169914/0/0/w_19r ...

  8. [转载]sublime用法精华

    Sublime Text 全程指南 九月 03.2015. 暂无评论 永远站 作者:Lucida 原文链接:http://lucida.me/blog/sublime-text-complete-gu ...

  9. Android精通之AsyncTask与ListView讲解

    版权声明:未经博主允许不得转载 AsyncTask 了解AsyncTask异步,需要了解一下异步任务(多线程),什么是线程,可以这么说线程好比边吃饭边看电视,AsyncTask是为了方便后台线程中操作 ...

随机推荐

  1. Ansible进阶

    YAML YAML简介 YAML是一个可读性高,并用来表达资料序列的格式.YAML参考了其它多种语言,包括:XML.C语言.Python.Perl以及电子邮件格式RFC2822等 它是一种直观的能够被 ...

  2. Maven单元测试

    // SKU码:系列前3位+6位年月日+3位序号(自动生产,取数据库中当天最大的,没有就赋值位001) // 订单编号:BRD+6位年月日+5位序号 // // 退单号:BRT+6位年月日+3位序号 ...

  3. 使用Sharesdk实现第三方平台登录(qq,新浪微博)

    首先到sharesdk开放píng台下载demo ,以下要用到的文件来自于 simple里面 第一步:导入官方的jar包    第二步:添加ShareSDK.xml文件并修改相关píng台key  第 ...

  4. BZOJ 2957 楼房重建 (线段树)

    题目链接  楼房重建 解题思路:我们可以把楼房的最高点的斜率计算出来.那么问题就转化成了实时查询x的个数,满足数列x的左边没有大于等于x的数. 我们可以用线段树维护 设t[i]为如果只看这个区间,可以 ...

  5. ZOJ - 4016 Mergeable Stack (STL 双向链表)

    [传送门]http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4016 [题目大意]初始有n个空栈,现在有如下三种操作: (1) ...

  6. GeoServer发布Heatmap

    转自原文 GeoServer发布Heatmap 百度等热力图是使用开源的heatmap.js做的,但是这种解决方案的缺陷是: 1 数据量大的话,从前端通过后台查询比较费时,比如arcserver默认设 ...

  7. 《ASP.NET》数据绑定—DataList实践篇

    上篇文章大概讲了DataList的一些基础知识,掌握这些知识在将来的应用中起到非常大的作用,如今我们就開始讲上篇文章中说的基础知识做一个小样例. 首先,我机子的数据库中有一张person表.例如以下图 ...

  8. jQuery -&gt; 获取后代元素的三种方法

    假设我们有内容例如以下的html文件,那么怎样选取包括在<p>元素内的<i>元素呢? 邪馬台国の謎と弥生時代 紀元前1000年ごろ.水稲工作の技術をもつ集団が大挙して日本に移住 ...

  9. Ubuntuserver版安装

          近期因为工作的须要.又一次部署server.安装了Ubuntuserver版本号,依据当时遇到的一些问题,整理了下,为方便以后的使用做个记录.       因为直接安装server端.无法 ...

  10. 【前端】怎样成长为一名优秀的前端project师---

    浅谈本人的经验.也算是与大家交流吧,本人眼下也是从事前端的工作,时间并不长,说的不好,请见谅. 首先,前端project师必须得掌握HTML.CSS和JavaScript. 仅仅懂当中一个或两个还不行 ...