详解Android 中AsyncTask 的使用
详解Android中AsyncTask的使用
1、首先我们来看看AsyncTask的介绍:
Handler和AsyncTask都是android中用来实现异步任务处理的方式;其中:
Handler实例向UI线程发送消息,完成界面更新,
优点:对整个过程控制的比较精细;
缺点:代码相对臃肿,多个任务同时执行时,不易对线程进行精确的控制;
AsyncTask:比Handler更轻量级一些,适用于简单的异步处理;
优点:简单|快捷|过程可控;
缺点:使用多个异步操作时就变得复杂起来;
2、AsyncTask的定义:(AsyncTask定义了三种泛型类型)
publicabstractclassAsyncTask{...}
说明:
Params:启动任务执行的输入参数,例如:HTTP请求的URL;
Progress:后台任务执行的百分比;
Result:后台执行任务最终返回的结果,比如String;
3、AsyncTask异步任务的执行步骤:(以下方法除execute(Params...params),在AsyncTask中重写),下列是相关方法的介绍:
A、execute(Params...params):
执行一个异步任务,需要我们在UI线程中调用,触发任务
B、OnPreExecute():
execute(Params...params)调用后立即执行,一般用于在执行后台任务前对UI做一些标记;例如,可以在此处显示进度对话框;
C、doInBackground(Params..params):
onPreExecute()完成后执行,后台执行,处理比较耗时的操作;此处不能操作UI,执行的过程中调用publishProgress(Progress...values)来更新进度信息;
D、onProgressUpdate(Progress...values):
在调用publicshProgress(Progress...values)方法执行,直接将进度信息更新到UI组建上;此方法在主线程上执行,用于显示任务执行的进度;
E、onPostExecute(Resultresult):
此方法在主线程中执行,当后台的操作结束时,此方法会被调用,计算结果作为参数传递到此方法中,直接将结果显示到UI组建上。
F、cancel();:
取消一个正在执行的任务,在UI线程中完成,用AsyncTask的对象进行调用,参数为true/false;
4、使用AsyncTask时注意事项:
A、异步任务实例必须在UI线程中创建;
B、execute(Params...params)方法必须在UI线程中调用;
C、不要手动的调onPreExecute().doInBackground().onProgressUpdate().onPostExecute()这几个方法;
D、不能在doInBackground(Params...params)中更改组件信息;
E、一个任务实例只能执行一次,如果执行第二次会抛出异常;
5、案例:使用AsyncTask实现图片的下载:
Activity类,主程序的入口:
publicclassMainActivityextendsActivity{ //程序入口 protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyAsyncTaskmy=newMyAsyncTask(); my.execute("http://photocdn.sohu.com/20110927/Img320705637.jpg"); } }
AsyncTask派生类,实现异步任务:
packagecom.sun.asynctask; importjava.io.ByteArrayOutputStream; importjava.io.InputStream; importjava.net.HttpURLConnection; importjava.net.URL; importorg.apache.http.HttpConnection; importorg.apache.http.HttpEntity; importorg.apache.http.HttpResponse; importorg.apache.http.HttpStatus; importorg.apache.http.client.HttpClient; importorg.apache.http.client.methods.HttpGet; importorg.apache.http.impl.client.DefaultHttpClient; importandroid.graphics.Bitmap; importandroid.graphics.BitmapFactory; importandroid.os.AsyncTask; importandroid.util.Log; /** *异步任务,实现网页内容的获取 * * *生成该类的对象,并调用execute方法之后 * *首先执行的是onProExecute()方法, * *其次执行的doInBackground()方法 */ publicclassMyAsyncTaskextendsAsyncTask{ /** *在execute()方法执行后立即执行,运行在UI线程中, *在后台任务开始前执行,用于标识UI界面 */ protectedvoidonPreExecute(){ super.onPreExecute(); Log.i("msg","onPreExecute()..."); } /** *后台执行耗时的任务; * *方法中的String参数对应AsyncTask的第一个参数; *返回的Bitmap对应的是AsyncTask的第三个参数; * *该方法并不运行在UI线程中,主要用于异步操作,可以调用publishProgress()方法触发 *onProgressUpdate对UI进行操作; * */ protectedBitmapdoInBackground(String...params){ Log.i("msg","doInBackground(String...params)..."); try{ /*网络访问方式二*/ /* URLurl=newURL(params[0]); HttpsURLConnectionconnection=(HttpsURLConnection)url.openConnection(); connection.connect();//开始连接 intzong=connection.getContentLength(); InputStreamis2=connection.getInputStream(); */ /*开始网络访问数据*/ HttpGethg=newHttpGet(params[0]);//此处注意参数的用法 HttpClienthc=newDefaultHttpClient(); HttpResponsehr=hc.execute(hg);//发送请求,得到响应 //判断请求是否成功 if(hr.getStatusLine().getStatusCode()==HttpStatus.SC_OK){ Log.i("msg","accesssuccess..."); HttpEntityhe=hr.getEntity(); InputStreamis=he.getContent();//获取输入流对象,好比搭桥 longtotal=he.getContentLength();//文件的总字节数 ByteArrayOutputStreambaos=newByteArrayOutputStream();//输出流,临时容器,用于装从is中流出的数据 byte[]buffer=newbyte[1024];//缓存容器,每次装载1024个字节数据 intlen=0;//每次读的字节数 intcurLen=0;//已读多少数据 while((len=is.read(buffer))!=-1){//当len!=-1时,也就是还有数据可读 Log.i("msg","beginreaddata..."+len+",total:"+total); baos.write(buffer,0,len);//向临时容器中装数据 curLen=curLen+len;//更新已读的数据 /*在UI显示当前读取的进度,调用次方法触发onProgressUpdate()方法执行*/ publishProgress((int)(((float)curLen/total)*100)); } Bitmapbitmap=BitmapFactory.decodeByteArray(baos.toByteArray(),0,(int)total); is.close(); returnbitmap; } }catch(Exceptione){ e.printStackTrace(); } returnnull; } /** *括号中的参数:String对应的是AsyncTask的第三个参数,也就是 *接收了从doInBackground()返回的结果; *此方法在doInBackground()方法执行结束后执行,运行在UI线程中, *可以对UI进行更新 */ protectedvoidonPostExecute(Bitmapresult){ super.onPostExecute(result); Log.i("msg","onPostExecute(Stringresult)..."+result.getHeight()); } /** *方法括号中的Integer对应AsyncTask中的第二个参数; *在doInBackground()中每次调用publishProgress()时被执行; *该方法是在UI线程中的,所以可以用于对UI进行更新 */ protectedvoidonProgressUpdate(Integer...values){ super.onProgressUpdate(values); Log.i("msg","onProgressUpdate(Integer...values)..."+values[0]); } /** *图片的下载 */ publicHttpURLConnectiondownPic(Stringurltemp){ try{ URLurl=newURL(urltemp);//确定连接地址 //打开一个连接 HttpURLConnectionconnection=(HttpURLConnection)url.openConnection(); connection.connect();//开始连接 returnconnection; }catch(Exceptione){ e.printStackTrace(); } returnnull; } }
以上就是AndroidAsyncTask的应用实例,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!