实例讲解Android中AsyncTask的使用详解
来源:互联网 发布:vb str是什么意思 编辑:程序博客网 时间:2024/06/15 16:07
——热爱开源,乐于分享
实例讲解Android中的AsyncTask的使用详解
一、单线程模型
在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则:
1. 不要阻塞UI线程
2. 确保只在UI线程中访问Android UI工具包
二、为什么要使用AsyncTask?
基于单线程模型原则,我们需要将耗时操作放在UI线程以外,进行多线程处理,在Android中实现多线程任务机制有两种方式,Handler和AsyncTask。
1.Hnadler:
Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。
2.AsyncTask:
AsyncTask是android提供的一个助手类,它对Thread和Handler进行了封装,方便我们使用。Android之所以提供AsyncTask这个类,就是为了方便我们在后台线程中执行操作,然后将结果发送给主线程,从而在主线程中进行UI更新等操作。在使用AsyncTask时,我们无需关注Thread和Handler,AsyncTask内部会对其进行管理,这样我们就只需要关注于我们的业务逻辑即可。
三、AsyncTask的5个回调方法及其之间的关系和作用
1.execute(Params… params):
启动执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute():
在execute(Params… params)被调用后立即执行,一般用来在执行后台任务前对UI做一些初始化操作。
3.doInBackground(Params… params):
在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress… values)来更新进度信息。
4.onProgressUpdate(Progress… values):
在调用publishProgress(Progress… values)时,此方法才会被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result):
当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
在使用的时候,需注意:
1.异步任务的实例对象(new AsyncTask)必须在UI线程中创建。
2.execute(Params… params)方法必须在UI线程中调用。
3.不要手动调用onPreExecute(),doInBackground(Params… params),onProgressUpdate(Progress… values),onPostExecute(Result result)这几个方法。
4.不能在doInBackground(Params… params)中更改UI组件的信息。
四、实例详解
下面使用一个简单例子详细说明AsyncTask的具体用法:
(实现的功能:点击Button,实现网络图片下载)
(直接上代码,因为我已经在代码里面把注释写的非常清楚了)
1.先看一下工程结构:
2.activity_main.xml
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.administrator.myasynctask.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="image test" android:onClick="loadImage" tools:layout_editor_absoluteX="147dp" tools:layout_editor_absoluteY="36dp" /></android.support.constraint.ConstraintLayout>
3.image.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:padding="16dp" android:layout_height="match_parent"> <ImageView android:id="@+id/img" android:layout_width="match_parent" android:layout_height="match_parent" /> <ProgressBar android:id="@+id/progressbar" android:visibility="gone" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /></RelativeLayout>
4.MainActivity.java
package com.example.administrator.myasynctask;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //button的点击事件,在xml中写的onClick public void loadImage(View view){ startActivity(new Intent(this,ImageTest.class)); }}
5.ImageTest.java
package com.example.administrator.myasynctask;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.View;import android.widget.ImageView;import android.widget.ProgressBar;import java.io.BufferedInputStream;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;/** * Created by Administrator on 2017/7/14. */public class ImageTest extends Activity { private ImageView mImageView;//显示图片的ImageView private ProgressBar mProgressBar;//圆形进度条,在XML中默认设置为隐藏的 private static String URL = "http://pic1.win4000.com/wallpaper/2/5603c62c082ca.jpg"; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image); mImageView= (ImageView) findViewById(R.id.img); mProgressBar=(ProgressBar) findViewById(R.id.progressbar); new MyAsyncTask().execute(URL);//启动异步线程时,所需要传递的参数,与AsyncTask<String, Void, Bitmap>定义的一致 } //创建一个asynctask,继承自AsyncTask<String, Void, Bitmap>,用于连接网络,下载图片; //三个参数分别是:传入的参数的类型(可变长度的参数)、后台任务执行的进度(一般用于条状progressbar,此处为圆形,不需要,故为void)、返回的结果的类型; //在下面的几个重写方法中的参数与这三个参数是一致的、关联的; class MyAsyncTask extends AsyncTask<String, Void, Bitmap>{ //该方法在doInBackground之前执行,一般用于初始化操作 @Override protected void onPreExecute() { super.onPreExecute(); mProgressBar.setVisibility(View.VISIBLE);//显示进度条(默认是不显示的) } //该方法在doInBackground之后(即耗时操作完成)执行 @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); mProgressBar.setVisibility(View.GONE);//隐藏进度条 mImageView.setImageBitmap(bitmap); } //该方法执行耗时操作的具体实现 @Override protected Bitmap doInBackground(String... params) { //获取传递进来的参数 String url=params[0]; Bitmap bitmap=null; URLConnection connection; InputStream is; try { //从网络下载图片的方法!!!!!!!! connection =new URL(url).openConnection();//打开网络连接对象 is=connection.getInputStream();//获取连接输入流 BufferedInputStream bis=new BufferedInputStream(is);//封装输入流 bitmap = BitmapFactory.decodeStream(bis);//利用工厂方法将输入流转换为bitmap //关闭流 is.close(); bis.close(); } catch (IOException e) { e.printStackTrace(); } //返回bitmap,与第三个参数bitmap(result)一致 return bitmap; } }}
6.别忘了在AndroidManifest.xml文件中注册
<activity android:name=".ImageTest"/>
效果展示:
- 实例讲解Android中AsyncTask的使用详解
- AsyncTask---详解Android中AsyncTask的使用
- 【AsyncTask】详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- (转)详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- 详解Android中AsyncTask的使用
- JavaWeb学习总结(五十)——文件上传和下载
- VS2012+QT+openGL编译错误
- MySQL索引专题一 认识索引
- 【Mongo】 批量删除集合
- spring-boot Feign
- 实例讲解Android中AsyncTask的使用详解
- Unix环境编程之 进程控制
- Qt5 中对 C++11 一些新特性的封装详解(一)
- tomcat部署简单的html静态网页
- code length overflow jquery qrcode
- Java实现二叉树
- 获取微信公众号的二维码图片
- bzoj 4145: [AMPPZ2014]The Prices 状压dp
- hive表信息查询:查看表结构、表操作等