Android_AsyncTask
来源:互联网 发布:朝鲜第五次核试验 知乎 编辑:程序博客网 时间:2024/06/06 01:26
Android_AsyncTask
我在上一篇的Blog中介绍了Android中多线程之间的通信–Handler消息机制,如果你不是那么的理解。今天就让我们学习一下,Android帮我们做了很好的一个封装工具—AsyncTask(AsyncTask可以十分简单的从子线程切换到主线程。)
在学习AsyncTask之前,我们还是先了解一下AsyncTask是什么?使用它需要传入那些参数。和它都具有什么方法。
AsyncTask是一个自动在子线程执行任务,并且自动实现了在主线程对进度和结果更新的一个异步任务类,开发者只需要将不同的代码重写在不同的方法即可。
继承AsyncTask参数说明
AsyncTask是一个抽象类,通常需要自定义类,继承自AsyncTask,
在继承时,需要指定3个泛型的数据类型,分别表示:
1、(params)执行任务时所需要的参数的数据类型、
2、(Progress)执行任务过程中如果需要更新进度,表示进度的数据类型、
3、(Result)执行任务完成之后,结果的数据类型。
部分任务可能不需要以上3种中的某些数据类型,通常使用Void类型进行标识。
AsyncTask中的方法
1、onPreExecute()
这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框。
2、doInBackground(Params …)
这个方法中的所有代码都是在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一单完成就可以通过return语句来讲任务的执行结果返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publicProgress(Progress…)
3、onProgressUpdate(Progress…)
当在后台任务中调用了publicProgress(Progress…)方法后,这个方法就会很快被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值可以对界面元素进行相应地更新。
4、onPostExecute(Result)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如关闭掉进度条对话框。
通过对上面对AsyncTask的讲解,你应该没有那么迷茫了,现在我们就通过一个小实例来具体的体会一下吧。我的这个实例很简单,就是点击按钮去下载网络中的一张图片,并显示在ImageView中。
1、下面先给大家我的activity_main.xml布局文件的代码:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout 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" tools:context="com.example.asynctasktest.MainActivity"> <Button android:id="@+id/main_DownloadBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="点击下载图片" android:textSize="18sp" /> <ImageView android:id="@+id/main_iv_show" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/main_DownloadBtn" android:src="@mipmap/ic_launcher"/></RelativeLayout>
2、下面让我们来看一下MainActivity中的具体逻辑代码:
public class MainActivity extends Activity { private Button downLoadBtn; private ImageView ivShowImage; //图片的URL private String IMAGE_PATH = "http://d.hiphotos.baidu.com/image/w%3D2048/sign=232a6514be315c6043956cefb989ca13/c83d70cf3bc79f3d3b082d31b8a1cd11738b29c2.jpg"; private ProgressDialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置Activity没有标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); downLoadBtn = (Button) findViewById(R.id.main_DownloadBtn); ivShowImage = (ImageView) findViewById(R.id.main_iv_show); dialog = new ProgressDialog(this); //用户不可以点击取消 dialog.setCancelable(false); dialog.setMessage("正在下载图片,请耐心等待--"); //显示一个百分比进度条,不加就显示默认的圈圈 dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); downLoadBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new InnerAsyncTask().execute(IMAGE_PATH); } }); } /*** * 自定义InnerAsyncTask继承AsyncTask */ class InnerAsyncTask extends AsyncTask<String, Integer, byte[]> { //使用HttpURLConnection请求,我在AndroidStudio中没有发现HttpClient HttpURLConnection connection = null; URL url = null; InputStream inputStream = null; //返回的图片的内容 byte[] result = null; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); @Override protected void onPreExecute() { super.onPreExecute(); //显示进度条 dialog.show(); } @Override protected byte[] doInBackground(String... params) { try { url = new URL(params[0]); connection = (HttpURLConnection) url.openConnection(); int file_length = connection.getContentLength(); int totle_length = 0; byte[] data = new byte[1024]; int len = 0; if (connection.getResponseCode() == 200) { inputStream = connection.getInputStream(); while ((len = inputStream.read(data)) != -1) { totle_length += len; int progress_value = (int) (totle_length / (float) file_length); //发布刻度单位 publishProgress(progress_value); outputStream.write(data, 0, len); } } result = outputStream.toByteArray(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (connection != null) { connection.disconnect(); } } return result; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); //设置进度条的显示进度 dialog.setProgress(values[0]); } @Override protected void onPostExecute(byte[] result) { super.onPostExecute(result); Bitmap bm = BitmapFactory.decodeByteArray(result, 0, result.length); //给ImageView设置Bitmap对象 ivShowImage.setImageBitmap(bm); //显示出来图片后将进度条消失 dialog.dismiss(); } }}
注意
AsyncTask的执行特性是一把双刃剑,当存在多个AsyncTask时,所有的AsyncTask会依据启动的顺序依次执行,而并不会存在多个任务的多个子线程同时运行的状况
如果你感觉上面的内容比较简单,可以看一下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详解及其应用(二 )_RejectedExecutionException问题
- Android_AsyncTask详解及其应用(二 )_RejectedExecutionException问题
- android_AsyncTask与Handler的相同点跟区别
- Android_AsyncTask详解及其应用(三)_图片错位以及AsyncTask重复创建的问题
- 关于适应不同尺寸设备的问题
- 选择图片或拍照剪切后上传服务器
- 消息队列(Message Queue)简介及其使用
- 图的创建及深度搜索广度搜索等可运行
- 如何用segment实现选择栏
- Android_AsyncTask
- Spring Boot的Profile切换方式
- java中JFrame类的简介
- textarea:contenteditable模拟文本域-纯文本-chrome浏览器,其余不兼容
- caffe模型微调
- How to Build an High Availability MQTT Cluster for the Internet of Things
- 实现统一社会信用代码校验
- seajs模块的加载启动
- ubuntu1404 ssh