标签:
转载请注明出处:http://blog.csdn.net/wei_chong_chong/article/details/50867756
AsyncTask封装,简化异步操作
.构建AsyncTask子类的参数
AsyncTask<Params,Progress,Result>是一个抽象类
通常用于被继承,继承AnyncTask需要指定如下三个泛型参数:
Params:启动任务时输入参数的类型。
Progress:后台任务执行中返回进度值的类型。
Result:后台任务执行完成后返回结果的类型
.构建AsyncTask子类的回调方法
doInBackground:必须重写,异步执行后台线程将要完成的任务
onPreExecute执行后台耗时操作前被调用,通常用户完成一些初始化操作
onPostExecute当doInBackground() 完成后系统会自动调用,并将doInBackground方法的返回值传递给该方法
onProgressUpdate:在doInBackground()f方法中调用publishProgress()方法更新任务的执行进度后,就会触发该方法
先做一个小实例:
从网络加载一张图片,在加载图片前显示一个ProgressBar提示用户等待
1.布局文件:
<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" android:padding="10dp" tools:context="com.example.myasynctask.MainActivity" > <ImageView android:id="@+id/image" android:layout_width="300dp" android:layout_height="300dp" /> <ProgressBar android:id="@+id/myPreogressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="加载网络图片" /> </RelativeLayout>
public class MainActivity extends Activity { private ImageView mImageView; private ProgressBar mProgressBar; private static String URL ="http://p2.so.qhimg.com/bdm/288_180_/t01d3443ce385e0af17.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageView = (ImageView) findViewById(R.id.image); mProgressBar = (ProgressBar) findViewById(R.id.myPreogressBar); } public void onclick(View view){ new MyAsycTaskTest().execute(URL); } class MyAsycTaskTest extends AsyncTask<String,Void, Bitmap>{ @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); mProgressBar.setVisibility(View.VISIBLE); } @Override protected void onPostExecute(Bitmap result) { // TODO Auto-generated method stub super.onPostExecute(result); mProgressBar.setVisibility(View.GONE); mImageView.setImageBitmap(result); } /** * 参数说明:第一个参数:传入执行任务的url,所以是String类型,第二个是进度值类型(这里不需要),第三个是返回值类型,这里是一张图片 * */ @Override protected Bitmap doInBackground(String... params) { // TODO Auto-generated method stub //参数是可变长数组 String url = params[0]; Bitmap bitmap = null; URLConnection connection; InputStream is; try { connection = new java.net.URL(url).openConnection(); is = connection.getInputStream();//获取输入流 Thread.sleep(3000);//模拟网速不好的情况,让它出现加载前的ProgressBar,实际开发中不能用 BufferedInputStream bis= new BufferedInputStream(is); bitmap = BitmapFactory.decodeStream(bis); is.close(); bis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return bitmap; } } }
下面来学习使用onProgressUpdate():在doInBackground()f方法中调用publishProgress()方法更新任务的执行进度后,就会触发该方法
模拟进度条
<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.myasynctask.ProgressBar_Test" > <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" /> </RelativeLayout>
public class ProgressBar_Test extends Activity { private ProgressBar mprogressbar; private MyAsycTask mTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_progress_bar__test); mprogressbar = (ProgressBar) findViewById(R.id.progressBar); mTask = new MyAsycTask(); mTask.execute(); } class MyAsycTask extends AsyncTask<Void, Integer, Void>{ @Override protected Void doInBackground(Void... params) { // TODO Auto-generated method stub //模拟进度更新 for(int i = 0;i <100;i++){ publishProgress(i);//传入更新值 try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); //获取进度更新值 mprogressbar.setProgress(values[0]); } } }
AsyncTask底部是使用线程池实现的,当一个线程task没有执行完毕,另一个线程task没法执行,如何解决?
解决方法:使AsyncTask得生命周期与Activity的生命周期一样
在活动的onPause()方法中加入ASyncTask的状态标记
protected void onPause() { // TODO Auto-generated method stub super.onPause(); if(mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING){ mTask.cancel(true);//cancle方法只是将对应的ASyncTask标记为cancle状态,并不能真正取消,真正取消该异步任务还需要我们在ASyncTask的方法中获取状态进行判断,是否执行 } }
protected Void doInBackground(Void... params) { // TODO Auto-generated method stub //模拟进度更新 for(int i = 0;i <100;i++){ //根据状态选择是否取消任务 if(isCancelled()){ break; } publishProgress(i);//传入更新值 try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); //根据状态选择是否取消更新 if (isCancelled()) { return; } //获取进度更新值进行更新 mprogressbar.setProgress(values[0]); }
总结:
AsyncTask注意事项:
1.必须在UI线程中创建AsyncTask的实例
2.必须在UI线程中调用ASyncTask的execute()方法
3.重写的四个方法是系统自动调用的,不应该手动调用
4.每个ASyncTask只能被执行一次,多次调用将会引发异常
标签:
原文地址:http://blog.csdn.net/wei_chong_chong/article/details/50867756