Android_AsyncTask
2016-06-06 14:13
453 查看
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源码讲解
相关文章推荐
- Qt for Android 开发大坑 2
- android ListView几种使用
- Android Studio中Git的配置及协同开发
- Android EventBus源码解析 带你深入理解EventBus
- Android Studio中Git的配置及协同开发
- Google Android开发者文档系列-创建有内容分享特性的应用之文件共享(序言)
- Android改变mediaController的位置
- Android drawable xml 各种小知识
- 基于SuperSocket的IIS主动推送消息给android客户端
- Android 6.0: 动态权限管理的解决方案
- android中的文件操作详解以及内部存储和外部存储
- First Day
- android am命令详解
- android手机屏幕适配的简单说明
- Android 获取屏幕宽度的4种
- Android手机适配,手机尺寸、px、dpi、dp、sp详解
- EventBus3 源码解读
- Android项目开发第四周学习总结
- Android——Android实现多级菜单联动操作
- 百度地图定位demo