<一>AsyncTask实现异步处理任务

在开发Android应用时必须遵守单线程模型的原则:AndroidUI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则:
1.不要阻塞UI线程
2.确保只在UI线程中访问AndroidUI工具包
当一个程序第一次启动时,Android会同时启动一个对应的主线程(MainThread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。
比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText().因为其他线程中是不能直接访问主UI线程成员


<二>Android提供了一些其他线程中访问UI线程的方法
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable,long)
Hanlder
但是这些类或方法都有一些问题。会使你的代码很复杂很难理解。实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。
为了解决这个问题,Android提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。

<三>AsyncTask操作步骤

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。

<1>子类化AsyncTask

AsyncTask是抽象类我们必须自己写一个类来继承AsyncTask 类

<2>实现AsyncTask中定义的下面方法 (很关键)

onPreExecute() 该方法将在执行实际的后台操作前被UIthread调用。这个方法只是做一些准备工作,如在界面上显示一个进度条。

doInBackground(Params...), 将在onPreExecute方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。

publishProgress 该方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。

onProgressUpdate(Progress...), publishProgress方法被调用后,UIthread将调用这个方法从而在界面上展示任务的进展情况,可以通过一个进度条进行展示。

onPostExecute(Result), doInBackground执行完成后,onPostExecute方法将被UIthread调用,后台的计算结果将通过该方法传递到UIthread.

<四>AsyncTask遵守准则

为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
<1>Task的实例必须在UIthread中创建
<2>execute方法必须在UIthread中调用
<3>不要手动的调用onPreExecute(),onPostExecute(Result)doInBackground(Params...),onProgressUpdate(Progress...)这几个方法
<4>task只能被执行一次,否则多次调用时将会出现异常

<五>AsyncTask的泛型

AsyncTask定义了三种泛型类型ParamsProgressResult
Params 启动任务执行的输入参数,比如HTTP请求的URL
Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String

不是所有类型都总是被异步任务使用。如果标记哪个参数不用,只是用void代替就可以了。

private class MyTask extends AsyncTask<Void, Void, Void> { ... }
<六>取消异步任务

只要调用cancel(boolean)方法,一个异步任务可以随时取消。调用这个方法会导致后来的调用isCancelled()返回true。

确保任务被取消尽可能快,你应该总是定期从doInBackground(Object[])中检查isCancelled()返回值。


Android进阶2之AsyncTask实现异步处理任务_第1张图片Android进阶2之AsyncTask实现异步处理任务_第2张图片


具体实现:

注意:添加网络权限:

 <uses-permission android:name="android.permission.INTERNET"/>
package xiaosi.asyncTask;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.Toast;public class AsyncTaskActivity extends Activity{private ImageViewimage= null;private Buttonshow;private ProgressBarprogressBar= null;private intnumber= 0;List<String>imageUrl= null;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);progressBar = (ProgressBar) findViewById(R.id.processBar);image = (ImageView) findViewById(R.id.image);show = (Button) findViewById(R.id.show);show.setOnClickListener(new showButtonListener());imageUrl = new ArrayList<String>(); // 图片地址ListimageUrl.add("http://image.tianjimedia.com/uploadImages/2011/266/AIO90AV2508S.jpg");imageUrl.add("http://image.tianjimedia.com/uploadImages/2012/090/063N2L5N2HID.jpg");imageUrl.add("http://comic.sinaimg.cn/2011/0824/U5237P1157DT20110824161051.jpg");imageUrl.add("http://image.tianjimedia.com/uploadImages/2012/090/1429QO6389U8.jpg");imageUrl.add("http://new.aliyiyao.com/UpFiles/Image/2011/01/13/nc_129393721364387442.jpg");}public class showButtonListener implements OnClickListener{@Overridepublic void onClick(View v){number++;MyAsyncTask myAsyncTask = new MyAsyncTask(AsyncTaskActivity.this);myAsyncTask.execute(imageUrl.get(number % 5));System.out.println("url:" + imageUrl.get(number % 5));}}class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>{// 可变长的输入参数,与AsyncTask.exucute()对应public MyAsyncTask(Context context){progressBar.setVisibility(View.VISIBLE);image.setVisibility(View.GONE);}@Overrideprotected Bitmap doInBackground(String... params){Bitmap bitmap = null;try{//new URL对象  把网址传入                  URL url = new URL(params[0]);                  //取得链接                  URLConnection conn = url.openConnection();                  conn.connect();                  //取得返回的InputStream                  InputStream inputStream = conn.getInputStream();                  //将InputStream变为Bitmap                  bitmap = BitmapFactory.decodeStream(inputStream);  if (image == null){Toast.makeText(getApplicationContext(), "下载出现异常", Toast.LENGTH_SHORT).show();}inputStream.close();}catch (Exception e){e.printStackTrace();}return bitmap;}/** * 在doInBackground 执行完成后,onPostExecute方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread. */@Overrideprotected void onPostExecute(Bitmap bitmap){progressBar.setVisibility(View.GONE);image.setVisibility(View.VISIBLE);if (bitmap != null){image.setImageBitmap(bitmap);}else{Toast.makeText(getApplicationContext(), "网络异常", Toast.LENGTH_SHORT).show();}}/** * 该方法将在执行实际的后台操作前被UI thread调用。这个方法只是做一些准备工作,如在界面上显示一个进度条。 */@Overrideprotected void onPreExecute(){// 任务启动Toast.makeText(getApplicationContext(), "任务开始......", Toast.LENGTH_SHORT).show();}}}


mian.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <Button        android:id="@+id/show"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="下一个" />    <ProgressBar           android:id="@+id/processBar"          android:layout_width="wrap_content"          android:layout_height="wrap_content"        android:visibility="gone"/>      <HorizontalScrollView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:scrollbars="none" >        <ImageView            android:id="@+id/image"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />    </HorizontalScrollView></LinearLayout>


更多相关文章

  1. android Matrix处理图片原理及方法整理
  2. Android 性能典范-线程
  3. android studio打开旧项目遇到build.gradle相关的问题解决方法
  4. android判断模拟器的三种方法

随机推荐

  1. android布局 LinearLayout和RelativeLayo
  2. Android中PopupWindow自定义坐标实现
  3. Android(安卓)屏幕旋转时保存状态
  4. Android(安卓)将View 转化为bitmap 图片
  5. Android(安卓)显示Emoji表情字符
  6. MAC中设置android adb环境变量
  7. 错误 'roundIcon' in package 'android'
  8. 读取android手机流量信息
  9. ViewModel、ViewModelProviders、ViewMod
  10. android 状态栏和导航栏(status and navi