实例讲解Android中AsyncTask的使用详解
2017-07-20 13:55
507 查看
——热爱开源,乐于分享
实例讲解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这个类,就是为了方便我们在后台线程中执
4000
行操作,然后将结果发送给主线程,从而在主线程中进行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的介绍及多实例并行方案详解
- Android 源码编译AIDL 使用实例讲解及Android Studio AIDL的调用详解
- 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的使用
- 详解Android中AsyncTask的使用