少年游

欲买桂花同载酒,终不似,少年游。

0%

Android之异步任务AsyncTask

AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

AsyncTask介绍

AsyncTask源码中有写到如何通过ThreadFactory管理Thread线程,不多介绍。
主要参数:

1
AsyncTask<Params, Progress, Result>

  • Params 启动任务执行的输入参数,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比。
  • Result 后台执行任务最终返回的结果,比如String。
    主要方法:
  • onPreExecute() 线程开始前执行(仍然是主线程)
  • doInBackground(Void… params) 异步执行(异步线程)
  • onPostExecute(String result) 线程结束后(主线程)
  • onProgressUpdate(Progress…) 进度条数据(主线程)

AsyncTask实例

场景:Fragment A提交数据给服务器,服务器返回数据给Fragment B,并更新B的UI

  1. Fragment A中写入内部类,写入异步任务
  2. onPreExecute()组建json格式数据,以url参数传值给服务器端
  3. doInBackground(Void… params)执行http请求,根据返回码判断执行是否请求成功!发送消息给主线程
  4. handler中接收消息解析code,并解析msg.obj,设置Activity全局变量setter
  5. onPostExecute(String result) 执行Fragment跳转
  6. Fragment加载Activity全局变量getter进入其UI数据
    SUCCESS!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
private final class AsyncImageTask extends AsyncTask<Void, Integer, String>{

private StringBuilder url= new StringBuilder("http://10.0.3.2:8080/medical_big_data/servlet/androidRequest?");
@Override
protected void onPreExecute() {
JSONObject status = new JSONObject();
try {
status.put("Age", dis_tv1.getText());
status.put("Height", dis_tv2.getText());
status.put("Weight", dis_tv3.getText());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("Target", status.toString());
url.append("json=["+status.toString()+"]");
}


@Override
protected String doInBackground(Void... params) {
int code;
try {
URL url = new URL(this.url.toString());
/**
* 这里网络请求使用的是类HttpURLConnection,另外一种可以选择使用类HttpClient。
*/
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setRequestMethod("GET");//使用GET方法获取
conn.setConnectTimeout(5000);
code = conn.getResponseCode();
Log.i("Target", code+"");
if (code == 200) {
/**
* 如果获取的code为200,则证明数据获取是正确的。
*/
InputStream is = conn.getInputStream();
String result = HttpUtils.readMyInputStream(is);

/**
* 子线程发送消息到主线程,并将获取的结果带到主线程,让主线程来更新UI。
*/
Message msg = new Message();
msg.obj = result;
msg.what = SUCCESS;
handler.sendMessage(msg);

} else {

Message msg = new Message();
msg.what = ERRORCODE;
handler.sendMessage(msg);
}
} catch (Exception e) {

e.printStackTrace();
/**
* 如果获取失败,或出现异常,那么子线程发送失败的消息(FAILURE)到主线程,主线程显示Toast,来告诉使用者,数据获取是失败。
*/
Message msg = new Message();
msg.what = FAILURE;
handler.sendMessage(msg);
}

return null;
}


@Override
protected void onPostExecute(String result) {
MPFragment mpFragment= new MPFragment();
FragmentTransaction transaction =getFragmentManager().beginTransaction();
transaction.replace(R.id.content,mpFragment);
transaction.addToBackStack(null);
transaction.commit();

}


}

异步线程和主线程通信

Message类
[int] msg.what 主要是设置code,可参看Message源码英文解释
[Object] msg.obj 主要是返回的数据对象

1
2
3
4
5
6
7
/**
* 子线程发送消息到主线程,并将获取的结果带到主线程,让主线程来更新UI。
*/
Message msg = new Message();
msg.obj = result;
msg.what = SUCCESS;
handler.sendMessage(msg);

主线程接收Message类Handler

必须实现handleMessage接收消息

1
2
3
4
5
6
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
/**
* 获取信息成功后,对该信息进行JSON解析,得到所需要的信息,然后在textView上展示出来。
*/
JSONAnalysis(msg.obj.toString());
Toast.makeText(getActivity(), "获取数据成功", Toast.LENGTH_SHORT)
.show();
break;

case FAILURE:
Toast.makeText(getActivity(), "获取数据失败", Toast.LENGTH_SHORT)
.show();
break;

case ERRORCODE:
Toast.makeText(getActivity(), "获取的CODE码不为200!",
Toast.LENGTH_SHORT).show();
break;
default:
break;
}
};
};