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
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" />
请看实现效果: