AsyncTask--异步任务
AsyncTask
Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。AsyncTask直接继承于Object类,位置为android.os.AsyncTask。
是Thread和Handler的帮助类,使用AsyncTask的时候,需要创建它的子类,至少要重写一个方法。
doInBackground()---》必须重写,做后台任务,并且可以把执行结果返回出去
onPostExecute(Result)--》非必需,但是通常情况下都会重写。接收doInBackground()的执行结果
创建异步任务对象,并且启动
New 子类().execute();
泛型1:doInBackground()的参数类型,
泛型2:后台任务执行进度
泛型3:doInBackground()的返回值的类型
注:泛型如果不需要的话,Void,如果请求网络,泛型不能为网络数据流!否则会出现android.os.NetworiOnMainThreadException
可选重写的四个方法
1、onPreExecute()执行在UI线程,比如弹出进度条2、doInBackGround(Params...)后台线程,执行耗时操作3、onProgressUpdate(Progress)执行在publishProgress()方法后4、onPostExecute执行在UI线程,用来更新UI
异步任务执行的顺序
1.onPreExecute():执行在UI线程。比如弹出进度框、进度条:
doInBackground(Params...)执行在后台线程。并且是紧跟2.onPreExecute()之后执行。在该方法中,可以执行耗时操作。execute()方法传递的参数会到doInBackground()的参数地方。返回值返回到onPostExcute()。在后台任务执行过程中,可以调用publishProgress(Progress...)发送进度,进度值被发送到UI Thread,到onPorgressUpdate()
3.onPorgressUpdate():执行在UIThread,并且是在调用了publishProgress(Progress...)之后执行。
4.onPostExecute(Result):执行在UI Thread,并且是在后台任务执行完成后才会执行,该方法的参数是后台任务的执行结果。
异步任务使用规则
1.异步任务的启动必须要在UI线程中
2.异步任务的创建,必须在UIThread
3.Excute()方法必须要在UI Thread线程中调用
4.重写来的方法,一定不要手动调用5.一个异步任务对象只能被启动一次
网络权限
在清单文件中的manifest节点下添加:
<uses-permission android:name="android.permission.INTERNET"/>
举例--请求一段网络json数据并展示到Spinner
MainActivity:
import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Spinner; import com.example.jsonparsefromservice.utils.getJsonString; import com.example.jsonparsefromservice.utils.parserJson;
public class MainActivity extends Activity { <span style="white-space:pre"> </span>private ProgressDialog pro; <span style="white-space:pre"> </span>private Spinner spinner; <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>protected void onCreate(Bundle savedInstanceState) { <span style="white-space:pre"> </span>super.onCreate(savedInstanceState); <span style="white-space:pre"> </span>setContentView(R.layout.activity_main); <span style="white-space:pre"> </span>spinner = (Spinner) findViewById(R.id.spinner); <span style="white-space:pre"> </span>}
public void btnClick(View view) { <span style="white-space:pre"> </span>String url = "http://litchiapi.jstv.com/api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41"; <span style="white-space:pre"> </span>new DownloadJson().execute(url); <span style="white-space:pre"> </span>}
<span style="font-family: Arial, Helvetica, sans-serif;"></span><pre name="code" class="java">//异步请求网络数据<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
private class DownloadJson extends AsyncTask<String, Void, String> {
<span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>protected void onPreExecute() { <span style="white-space:pre"> </span>super.onPreExecute(); <span style="white-space:pre"> </span>pro = new ProgressDialog(MainActivity.this); <span style="white-space:pre"> </span>pro.setMessage("加载中..."); <span style="white-space:pre"> </span>pro.show(); <span style="white-space:pre"> </span>}
// 耗时操作
<span style="white-space:pre"> </span>protected String doInBackground(String... params) { <span style="white-space:pre"> </span>Log.i("tag", "进入doIn"); <span style="white-space:pre"> </span>String result = getJsonString.getJson(params[0]); <span style="white-space:pre"> </span>Log.i("tag", "完成doIn"); <span style="white-space:pre"> </span>return result; <span style="white-space:pre"> </span>}
//展示数据,为spinner添加适配器
<span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>protected void onPostExecute(String result) { <span style="white-space:pre"> </span>super.onPostExecute(result); <span style="white-space:pre"> </span>List<String> data = parserJson.parseJSON(result); <span style="white-space:pre"> </span>ArrayAdapter<String> adapter = new ArrayAdapter<String>( <span style="white-space:pre"> </span>MainActivity.this, android.R.layout.simple_list_item_1, <span style="white-space:pre"> </span>data); <span style="white-space:pre"> </span>spinner.setAdapter(adapter); <span style="white-space:pre"> </span>pro.dismiss(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} }
public static String getJson(String url){ String result=null; HttpClient client=new DefaultHttpClient(); HttpPost post=new HttpPost(url); Log.i("tag", "准备获取json字符串"); try { HttpResponse res=client.execute(post); if(res.getStatusLine().getStatusCode()==200){ HttpEntity entity=res.getEntity(); result=EntityUtils.toString(entity); Log.i("tag", "获取到json字符串"); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } }
parserJSON()用来解析获得的json数据
package com.example.jsonparsefromservice.utils; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; public class parserJson { public static List<String> parseJSON(String jsonString) { Log.i("tag", "进入parseJSON"); Log.i("tag", jsonString); final List<String> data = new ArrayList<String>(); try { // 全部数据 JSONObject obj = new JSONObject(jsonString); // 列表数据及信息 JSONObject obj_list = obj.getJSONObject("paramz"); // 列表数据 JSONArray arr = obj_list.getJSONArray("feeds"); Log.i("tag", "将要循环添加subject"); for (int i = 0; i < arr.length(); i++) { JSONObject obj_list_msg = arr.getJSONObject(i); JSONObject obb = obj_list_msg.getJSONObject("data"); data.add(obb.getString("subject")); } } catch (JSONException e) { e.printStackTrace(); } return data; } }
XML文件比较简单,只放了了一个Button和Spinner
<Button android:id="@+id/btn_getMessage" android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="btnClick" android:text="获取数据" /> <Spinner android:id="@+id/spinner" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/btn_getMessage" />
请看实现效果:
在异步任务执行到onPreExecute()时,显示ProgressDialog对话框,提示正在加载:
执行到onPostExecute(),数据获取和解析完毕,更新UI。