Android AsyncTask实现异步处理任务的方法详解

发布时间 - 2026-01-11 00:50:14    点击率:

Android AsyncTask实现异步处理任务的方法详解

在开发Android应用时必须遵守单线程模型的原则:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。

Android 单线程模型概念详解:https://www./article/112165.htm

在单线程模型中始终要记住两条法则:

不要阻塞UI线程

确保只在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,它使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。

AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。

◆Params 启动任务执行的输入参数,比如HTTP请求的URL。

◆Progress 后台任务执行的百分比。

◆Result 后台执行任务最终返回的结果,比如String。

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。

子类化AsyncTask
实现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只能被执行一次,否则多次调用时将会出现异常

从网上获取一个网页,在一个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]); 
  } 
 
  } 
 
} 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# Android  # AsyncTask实现异步处理  # AsyncTask实现异步处理详解  # Android 使用AsyncTask实现多线程断点续传  # Android 使用AsyncTask实现断点续传  # Android 使用AsyncTask实现多任务多线程断点续传下载  # 详解Android 中AsyncTask 的使用  # Android多线程AsyncTask详解  # Android中使用AsyncTask实现下载文件动态更新进度条功能  # Android AsyncTask详解及使用方法  # Android带进度条的下载图片示例(AsyncTask异步任务)  # 浅谈Android中AsyncTask的工作原理  # 单线程  # 子类  # 将在  # 将其  # 源代码  # 很复杂  # 都是  # 进度条  # 几个  # 在这里  # 很难  # 不需要  # 当你  # 网上  # 而在  # 长时间  # 工具包  # 希望能  # 三种  # 将被 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)  浅析上传头像示例及其注意事项  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  如何用花生壳三步快速搭建专属网站?  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  网站制作报价单模板图片,小松挖机官方网站报价?  深入理解Android中的xmlns:tools属性  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  python中快速进行多个字符替换的方法小结  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  如何在自有机房高效搭建专业网站?  laravel怎么实现图片的压缩和裁剪_laravel图片压缩与裁剪方法  微信推文制作网站有哪些,怎么做微信推文,急?  Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】  Laravel怎么连接多个数据库_Laravel多数据库连接配置  Python正则表达式进阶教程_复杂匹配与分组替换解析  Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】  Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】  网页设计与网站制作内容,怎样注册网站?  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  javascript基于原型链的继承及call和apply函数用法分析  千库网官网入口推荐 千库网设计创意平台入口  如何用搬瓦工VPS快速搭建个人网站?  电商网站制作价格怎么算,网上拍卖流程以及规则?  Laravel如何使用Eloquent进行子查询  Laravel如何配置Horizon来管理队列?(安装和使用)  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  在线制作视频网站免费,都有哪些好的动漫网站?  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】  Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】  Python文件异常处理策略_健壮性说明【指导】  高防服务器租用指南:配置选择与快速部署攻略  java获取注册ip实例  phpredis提高消息队列的实时性方法(推荐)  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  Laravel怎么解决跨域问题_Laravel配置CORS跨域访问  android nfc常用标签读取总结  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  软银砸40亿美元收购DigitalBridge 强化AI资料中心布局  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  Android利用动画实现背景逐渐变暗  微信h5制作网站有哪些,免费微信H5页面制作工具?  昵图网官网入口 昵图网素材平台官方入口  Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道  如何快速搭建高效香港服务器网站?