В этом посте я сначала опишу, как использовать залп для динамического заполнения
ListView, а затем сравнить его с AsycnTask.
В этом посте мы будем вызывать удаленный сервис для получения контактной информации в формате JSON и заполнять элементы внутри ListView. Этот простой пример очень полезен для понимания библиотеки Volley и того, как мы можем ее интегрировать. Мы хотим получить что-то вроде изображения, показанного ниже:
Мы уже обсуждали эту тему в предыдущем посте , и это шанс подчеркнуть различные подходы ( Volley и AsyncTask ).
Залп JSONArrayRequest
Внутри Volley есть класс JsonArrayRequest , который можно использовать для получения массива JSON в качестве ответа. Как всегда, у нас два разных слушателя; мы должны реализовать:
- один, чтобы получить ответ
- еще один для обработки ошибок
Исходный код показан ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
JsonArrayRequest jReq = new JsonArrayRequest(url, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { List<Contact> result = new ArrayList<Contact>(); for ( int i = 0 ; i < response.length(); i++) { try { result.add(convertContact(response .getJSONObject(i))); } catch (JSONException e) { } } adpt.setItemList(result); adpt.notifyDataSetChanged(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // Handle error } }); |
В методе onResponse у нас есть объект JSONArray, который содержит ответ. В этом методе мы проходим массив json и преобразуем данные json в объект Contact , используя метод convert:
1
2
3
4
5
6
7
8
|
private final Contact convertContact(JSONObject obj) throws JSONException { String name = obj.getString( "name" ); String surname = obj.getString( "surname" ); String email = obj.getString( "email" ); String phoneNum = obj.getString( "phoneNum" ); return new Contact(name, surname, email, phoneNum); } |
В конце мы устанавливаем новый список контактов в нашем адаптере и вызываем:
1
|
adpt.notifyDataSetChanged(); |
Волей против AsyncTask
Теперь мы готовы сравнить Volley lib с AsycnTask . Как мы уже знаем, у AsyncTask есть некоторые проблемы, связанные с утечками памяти, поэтому мы должны использовать их осторожно. У Volley таких проблем нет, и мы можем использовать их каждый раз, когда нам нужен доступ к удаленному ресурсу. Более того, Volley упрощает код мы должны написать, чтобы вызвать удаленный сервис. В приведенном ниже коде я показываю эти два разных подхода:
01
02
03
04
05
06
07
08
09
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
|
private class AsyncListViewLoader extends AsyncTask<String, Void, List<Contact>> { private final ProgressDialog dialog = new ProgressDialog(MainActivity. this ); @Override protected void onPostExecute(List<Contact> result) { super .onPostExecute(result); dialog.dismiss(); adpt.setItemList(result); adpt.notifyDataSetChanged(); } @Override protected void onPreExecute() { super .onPreExecute(); dialog.setMessage( "Downloading contacts..." ); dialog.show(); } @Override protected List<Contact> doInBackground(String... params) { List<Contact> result = new ArrayList<Contact>(); try { URL u = new URL(params[ 0 ]); HttpURLConnection conn = (HttpURLConnection) u.openConnection(); conn.setRequestMethod( "GET" ); conn.connect(); InputStream is = conn.getInputStream(); // Read the stream byte [] b = new byte [ 1024 ]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ( is.read(b) != - 1 ) baos.write(b); String JSONResp = new String(baos.toByteArray()); JSONArray arr = new JSONArray(JSONResp); for ( int i= 0 ; i < arr.length(); i++) { result.add(convertContact(arr.getJSONObject(i))); } return result; } catch (Throwable t) { t.printStackTrace(); } return null ; } } |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
RequestQueue rq = Volley.newRequestQueue( this ); JsonArrayRequest jReq = new JsonArrayRequest(url, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { List<Contact> result = new ArrayList<Contact>(); for ( int i = 0 ; i < response.length(); i++) { try { result.add(convertContact(response .getJSONObject(i))); } catch (JSONException e) { } } adpt.setItemList(result); adpt.notifyDataSetChanged(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // Handle error } }); rq.add(jReq); |
Ясно, что используя Volley, у нас меньше строк кода, и нам не нужно беспокоиться об обработке HTTP-соединения.