为什么要用异步任务?
在Android中只有在主线程才能对ui进行更新操作,而其它线程不能直接对ui进行操作
android本身是一个多线程的操作系统,我们不能把所有的操作都放在主线程中操作 ,比如一些耗时操作。如果放在主线程中 会造成阻塞 而当阻塞事件过长时 系统会抛出anr异常。所以我们要使用异步任务。android为我们提供了一个封装好的组件asynctask。
AsyncTask可以在子线程中更新ui,封装简化了异步操作。适用于简单的异步处理。如果多个后台任务时就要使用Handler了 在这里就不再说明。
AsyncTask通常用于被继承。AsyncTask定义了三种泛型类型<Params,Progress,Result>
继承AsyncTask后要重写的方法有:
doInBackgroud:必须重写,异步执行后台线程要完成的任务,耗时任务要写在这里,并且在这里不能操作ui。可以调用 publishProgress方法来更新实时的任务进度
onPreExecute:执行耗时操作前调用,可以完成一些初始化操作
onPostExecute:在doInBackground 执行完成后,主线程调用此方法,可以在此方法中操作ui
onProgressUpdate:在doInBackgroud方法中调用publishProgress方法,更新任务的执行进度后 就会调用这个方法
下面通过一个实例来了解AsyncTask
首先附上运行结果
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btn_download" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="点击下载" /> <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/iv_image" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="fitCenter" /> </FrameLayout> </LinearLayout>
MainActivity
package com.example.asynctask; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URLConnection; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity implements OnClickListener{ private ImageView image; private ProgressDialog progress; private Button btn_download; private static String URL="http://img4.imgtn.bdimg.com/it/u=1256159061,743487979&fm=21&gp=0.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image=(ImageView) findViewById(R.id.iv_image); btn_download=(Button) findViewById(R.id.btn_download); progress=new ProgressDialog(this); progress.setIcon(R.drawable.ic_launcher); progress.setTitle("提示信息"); progress.setMessage("正在下载,请稍候..."); progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); btn_download.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub new MyAsyncTask().execute(URL); } /* * String*********对应我们的URL类型 * Integer********进度条的进度值 * BitMap*********异步任务完成后返回的类型 * */ class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>{ //执行异步任务(doInBackground)之前执行,并且在ui线程中执行 @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); if(image!=null){ image.setVisibility(View.GONE); } //开始下载 对话框进度条显示 progress.show(); progress.setProgress(0); } @Override protected Bitmap doInBackground(String... params) { // TODO Auto-generated method stub //params是一个可变长的数组 在这里我们只传进来了一个url String url=params[0]; Bitmap bitmap=null; URLConnection connection; InputStream is;//用于获取数据的输入流 ByteArrayOutputStream bos;//可以捕获内存缓冲区的数据,转换成html" target="_blank">字节数组。 int len; float count=0,total;//count为图片已经下载的大小 total为总大小 try { //获取网络连接对象 connection=(URLConnection) new java.net.URL(url).openConnection(); //获取当前页面的总长度 total=(int)connection.getContentLength(); //获取输入流 is=connection.getInputStream(); bos=new ByteArrayOutputStream(); byte []data=new byte[1024]; while((len=is.read(data))!=-1){ count+=len; bos.write(data,0,len); //调用publishProgress公布进度,最后onProgressUpdate方法将被执行 publishProgress((int)(count/total*100)); //为了显示出进度 人为休眠0.5秒 Thread.sleep(500); } bitmap=BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.toByteArray().length); is.close(); bos.close(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return bitmap; } //在ui线程中执行 可以操作ui @Override protected void onPostExecute(Bitmap bitmap) { // TODO Auto-generated method stub super.onPostExecute(bitmap); //下载完成 对话框进度条隐藏 progress.cancel(); image.setImageBitmap(bitmap); image.setVisibility(View.VISIBLE); } /* * 在doInBackground方法中已经调用publishProgress方法 更新任务的执行进度后 * 调用这个方法 实现进度条的更新 * */ @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); progress.setProgress(values[0]); } } }
最后不要忘记在AndroidManifest文件中配置网络访问权限
<uses-permission android:name="android.permission.INTERNET"/>
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持小牛知识库!
本文向大家介绍Android使用AsyncTask下载图片并显示进度条功能,包括了Android使用AsyncTask下载图片并显示进度条功能的使用技巧和注意事项,需要的朋友参考一下 在Android中实现异步任务机制有两种方式,Handler和AsyncTask。这篇文章给大家介绍Android使用AsyncTask下载图片并显示进度条功能。 AsyncTask下载图片并显示下载进度,异步类As
本文向大家介绍Android中使用AsyncTask做下载进度条实例代码,包括了Android中使用AsyncTask做下载进度条实例代码的使用技巧和注意事项,需要的朋友参考一下 android AsyncTask做下载进度条 AsyncTask是个不错的东西,可以使用它来做下载进度条。代码讲解如下: 配置文件 注意打开文件保存权限 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
本文向大家介绍Android的异步任务AsyncTask详解,包括了Android的异步任务AsyncTask详解的使用技巧和注意事项,需要的朋友参考一下 AsyncTask,顾名思义,异步任务。说到异步,最简单的理解就是不同步。再复杂一点理解,就得举例子了。 假设我要去火车站买票,刚到火车站我突然发现我忘了带身份证。怎么办?怎么办! 想办法,想办法!我想我应该找个在学校的同学帮我送过来,因为我不
本文向大家介绍PHP+Ajax无刷新带进度条图片上传示例,包括了PHP+Ajax无刷新带进度条图片上传示例的使用技巧和注意事项,需要的朋友参考一下 项目需求:1.PHP+Ajax无刷新带进度条图片上传,2.带进度条。所需插件:jquery.js,jquery.form.js。 最近在做一个手机web项目,需要用到Ajax上传功图片能,项目要求PHP无刷新上传图片,并且要带进度条,下面就来讲一下我的
主要内容:本节引言:,1.相关概念,2.AsyncTask全解析:,3.AsyncTask使用示例:,本节小结:本节引言: 本节给大家带来的是Android给我们提供的一个轻量级的用于处理异步任务的类:AsyncTask,我们一般是 继承AsyncTask,然后在类中实现异步操作,然后将异步执行的进度,反馈给UI主线程~ 好吧,可能有些概念大家不懂,觉得还是有必要讲解下多线程的概念,那就先解释下一些概念性的东西吧! 1.相关概念 1)什么是多线程: 答:先要了解这几个名称:应用程序,进程,线程,
本文向大家介绍Android中AsyncTask异步任务使用详细实例(一),包括了Android中AsyncTask异步任务使用详细实例(一)的使用技巧和注意事项,需要的朋友参考一下 AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程。 使用As