Статьи

Android Volley динамический ListView: сравнение AsyncTask

В этом посте я сначала опишу, как использовать залп для динамического заполнения
ListView, а затем сравнить его с AsycnTask.

В этом посте мы будем вызывать удаленный сервис для получения контактной информации в формате JSON и заполнять элементы внутри ListView. Этот простой пример очень полезен для понимания библиотеки Volley и того, как мы можем ее интегрировать. Мы хотим получить что-то вроде изображения, показанного ниже:

volley_listview_dynamic [4]

Мы уже обсуждали эту тему в предыдущем посте , и это шанс подчеркнуть различные подходы ( 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-соединения.