Android AsyncTask使用样例.docx
《Android AsyncTask使用样例.docx》由会员分享,可在线阅读,更多相关《Android AsyncTask使用样例.docx(15页珍藏版)》请在冰豆网上搜索。
AndroidAsyncTask使用样例
先大概认识下Android.os.AsyncTask类:
* android的类AsyncTask对线程间通讯进行了包装,提供了简易的编程方式来使后台线程和UI线程进行通讯:
后台线程执行异步任务,并把操作结果通知UI线程。
* AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
* Params 启动任务执行的输入参数,比如HTTP请求的URL。
*Progress 后台任务执行的百分比。
*Result 后台执行任务最终返回的结果,比如String,Integer等。
* AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现这些方法。
*1) 继承AsyncTask
*2) 实现AsyncTask中定义的下面一个或几个方法
* onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。
可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
* doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。
这里将主要负责执行那些很耗时的后台处理工作。
可以调用 publishProgress方法来更新实时的任务进度。
该方法是抽象方法,子类必须实现。
* onProgressUpdate(Progress...),在publishProgress方法被调用后,UI 线程将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
* onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户.
* onCancelled(),在用户取消线程操作的时候调用。
在主线程中调用onCancelled()的时候调用。
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1)Task的实例必须在UI线程中创建
2)execute方法必须在UI线程中调用
3)不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...)这几个方法,需要在UI线程中实例化这个task来调用。
4)该task只能被执行一次,否则多次调用时将会出现异常
doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。
样例效果如下图所示:
样例代码如下:
packagecom.example.asynctask;
importjava.io.BufferedInputStream;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.lang.ref.WeakReference;
import.HttpURLConnection;
import.URL;
importandroid.app.Activity;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.os.AsyncTask;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.util.Log;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.ImageView;
importandroid.widget.ProgressBar;
importandroid.widget.TextView;
publicclassAsyncTaskSampleActivityextendsActivity
{
ButtondownloadBtn;//下载按钮
ProgressBarpBar;//进度条
TextViewtView;//文字视图
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pBar=(ProgressBar)findViewById(R.id.pBar);
tView=(TextView)findViewById(R.id.tView);
downloadBtn=(Button)findViewById(R.id.downloadBtn);
downloadBtn.setOnClickListener(newOnClickListener()//为下载按钮设置监听器
{
@Override
publicvoidonClick(Viewv)
{
BitmapDownloaderTasktask=newBitmapDownloaderTask((ImageView)findViewById(R.id.imageView));//实例化AsyncTask
task.execute(getString(R.string.url));//启动AsyncTask
//执行excute可以传入多过个参数
//task.execute(getString(R.string.url),getString(R.string.url1),getString(R.string.url2),getString(R.string.url3));//启动AsyncTask
downloadBtn.setClickable(false);
}
});
}
/*
*实现抽象类AsyncTask:
实现时指定3个参数类型,分别用于如下:
*第一个参数:
String,用于doInBackground方法的输入参数
*第二个参数:
Integer,用于onProgressUpdate方法的输入参数
*第三个参数:
Bitmap,作为doInBackground的返回值类型以及onPostExecute的输入参数
*上述三个参数在实现AsyncTask抽象类时,可以根据实际情况使用不同类型,不局限于上述类型
*/
classBitmapDownloaderTaskextendsAsyncTask
{
privatefinalWeakReferenceimageViewRef;//使用WeakReference解决内存问题
publicBitmapDownloaderTask(ImageViewimageView)
{
imageViewRef=newWeakReference(imageView);
}
/*
*该方法将在执行实际的后台操作前被UI线程调用。
*可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
*@seeandroid.os.AsyncTask#onPreExecute()
*/
@Override
protectedvoidonPreExecute()
{
//TODOAuto-generatedmethodstub
super.onPreExecute();
tView.setText(getString(R.string.progressTxt));
Log.d("PortfolioManger","onPreExecute.......................1");
}
/**
*在onPreExecute方法执行后马上执行,该方法运行在后台线程中。
这里将主要负责执行那些很耗时的后台处理工作。
*可以调用publishProgress方法来更新实时的任务进度。
该方法是抽象方法,子类必须实现
*/
@Override
protectedBitmapdoInBackground(String...params)
{
//TODOAuto-generatedmethodstub
Log.d("PortfolioManger","doInBackground.......................2");
Stringpath=Environment.getExternalStorageDirectory()+"/download/";
StringfileName="logo1.png";
Log.v("PortfolioManger","PATH:
"+path);
Filefile=newFile(path);
file.mkdirs();
downloadFromUrl(params[0],path,fileName,this);
//downloadFromUrl(params,path,fileName,this);//传入多过个图片网址
returnBitmapFactory.decodeFile(path+fileName);
}
/*
*在publishProgress方法被调用后,UI线程将调用这个方法从而在界面上展示
*任务的进展情况,例如通过一个进度条进行展示。
*@seeandroid.os.AsyncTask#onProgressUpdate(Progress[])
*/
@Override
protectedvoidonProgressUpdate(Integer...progress)
{
//TODOAuto-generatedmethodstub
super.onProgressUpdate(progress);
tView.setText(progress[0]+"%");
Log.d("PortfolioManger","onProgressUpdate.......................3");
}
/*在doInBackground执行完成后,onPostExecute方法将被UI线程调用,
*后台的计算结果将通过该方法传递到UI线程,并且在界面上展示给用户
*@seeandroid.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protectedvoidonPostExecute(Bitmapresult)
{
//TODOAuto-generatedmethodstub
setTitle(getString(RpleteInfo));
if(isCancelled())
{
result=null;
}
if(imageViewRef!
=null)
{
ImageViewimageView=imageViewRef.get();
if(imageView!
=null)
{
imageView.setImageBitmap(result);//下载完设置imageview为刚才下载的bitmap对象
}
}
downloadBtn.setClickable(true);
//super.onPostExecute(result);
Log.d("PortfolioManger","onPostExecute.......................4");
}
/**
*联网下载图片并调用进度条和发布更新状态到UI线程
*@paramgoUrl下载图片的地址
*@parampath存储下载图片的路径
*@paramfileName存储图片的文件名
*@paramtaskAsyncTask
*/
publicvoiddownloadFromUrl(StringgoUrl,Stringpath,StringfileName,BitmapDownloaderTasktask)
{
StringsdStatus=Environment.getExternalStorageState();
if(!
sdStatus.equals(Environment.MEDIA_MOUNTED))
{
Log.d("PortfolioManger","SDcardisnotavaiable/writeablerightnow.");
return;
}
FileOutputStreamfos=null;
BufferedInputStreambis=null;
HttpURLConnectionconn=null;
try
{
URLurl=newURL(goUrl);
conn=(HttpURLConnection)url.openConnection();
//conn.connect();
intfileLen=conn.getContentLength();
doublereadLen=0;
fos=newFileOutputStream(path+"/"+fileName);
bis=newBufferedInputStream(conn.getInputStream());
byte[]buffer=newbyte[1024];
intlen1=0;
while((len1=bis.read(buffer))!
=-1)
{
fos.write(buffer,0,len1);
readLen+=len1;
intrate=(int)(readLen/fileLen*100);
Log.d("PortfolioManger","readLen="+readLen+".....fileLen="+fileLen+"....rate="+rate);
pBar.setProgress(rate);//设置进度条的进度
task.publishProgress(rate);//发布更新状态到UI线程中
}
if(fos!
=null)fos.close();
if(bis!
=null)bis.close();
}
catch(IOExceptione)
{
Log.d("PortfolioManger","Error:
"+e);
}
finally
{
if(conn!
=null)conn.disconnect();
}
Log.v("PortfolioManger","Check:
");
}
/**
*联网下载图片并调用进度条和发布更新状态到UI线程
*@paramgoUrls下载图片的地址数组
*@parampath存储下载图片的路径
*@paramfileName存储图片的文件名
*@paramtaskAsyncTask
*/
publicvoiddownloadFromUrl(StringgoUrls[],Stringpath,StringfileName,BitmapDownloaderTasktask)
{
StringsdStatus=Environment.getExternalStorageState();
if(!
sdStatus.equals(Environment.MEDIA_MOUNTED))
{
Log.d("PortfolioManger","SDcardisnotavaiable/writeablerightnow.");
return;
}
FileOutputStreamfos=null;
BufferedInputStreambis=null;
HttpURLConnectionconn=null;
intcount=goUrls.length;
for(inti=0;i{
try
{
URLurl=newURL(goUrls[i]);
conn=(HttpURLConnection)url.openConnection();
//conn.connect();
Log.d("PortfolioManger","goUrls["+i+"]:
"+goUrls[i]);
intfileLen=conn.getContentLength();
doublereadLen=0;
fos=newFileOutputStream(path+"/"+fileName);
bis=newBufferedInputStream(conn.getInputStream());
byte[]buffer=newbyte[1024];
intlen1=0;
while((len1=bis.read(buffer))!
=-1)
{
fos.write(buffer,0,len1);
readLen+=len1;
intrate=(int)(readLen/fileLen*100);
Log.d("PortfolioManger","readLen="+readLen+".....fileLen="+fileLen+"....rate="+rate);
pBar.setProgress(rate);//设置进度条的进度
task.publishProgress(rate);//发布更新状态到UI线程中
}
if(fos!
=null)fos.close();
if(bis!
=null)bis.close();
}
catch(IOExceptione)
{
Log.d("PortfolioManger","Error:
"+e);
}
finally
{
if(conn!
=null)conn.disconnect();
}
}
Log.v("PortfolioManger","Check:
");
}
}
}
布局文件main.xml代码如下:
xmlversion="1.0"encoding="utf-8"?
>
xmlns:
android="
android:
orientation="vertical"
android:
layout_width="fill_parent"
android:
layout_height="fill_parent">
android:
layout_width="fill_parent"
android:
layout_height="wrap_content"
android:
text="Hello,it'sasampleofasyncTask"/>