Неожиданный null в результате

Ответить
Lemme
Сообщения: 16
Зарегистрирован: 29 янв 2015, 23:38

Неожиданный null в результате

Сообщение Lemme » 05 фев 2015, 08:36

В чем тут может быть проблема, почему в цикле data наполняется, а при возвращении null?
Извините за такие глупые вопросы, но уже сколько бьюсь над этим и ничего сделать не могу...

Код: Выделить всё

package com.example.newtestapp;

import android.content.Context;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class Api {

    public final String ATTRIBUTE_NAME_TITLE = "title";
    public final String ATTRIBUTE_NAME_DATE = "date";
    public final String ATTRIBUTE_NAME_IMAGE = "img";

    private RequestQueue queue;
    ArrayList<Map<String, Object>> data;

    public Api (Context context) {
        queue = Volley.newRequestQueue(context);
    }

    public ArrayList<Map<String, Object>> getPosts() {
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://indpre.ru/test/", null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONArray posts = response.getJSONArray("posts");
                    data = new ArrayList<>(posts.length());
                    Map<String, Object> m;

                    int img = R.drawable.ic_launcher;

                    for (int i = 0; i < posts.length(); i++) {
                        JSONObject post = posts.getJSONObject(i);

                        m = new HashMap<>();
                        m.put(ATTRIBUTE_NAME_IMAGE, img);
                        m.put(ATTRIBUTE_NAME_TITLE, post.getString("title"));
                        m.put(ATTRIBUTE_NAME_DATE, post.getString("data"));
                            
                        data.add(m);
                        // Тут все хорошо
                        System.out.println(data);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        queue.add(jsonObjectRequest);
        // а тут уже null
        return data;
    }
}

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Неожиданный null в результате

Сообщение klblk » 05 фев 2015, 09:06

С volley не работал, но думаю проблема тут:
Надо:
1) отправить запрос
2) получить данные
3) использовать данные

у вас:
1) отправить запрос
2) использовать данные
3) получить данные

Т.е. строчка "return data;" выполнится еще до того как это самая data чем-то заполнится.

Lemme
Сообщения: 16
Зарегистрирован: 29 янв 2015, 23:38

Re: Неожиданный null в результате

Сообщение Lemme » 05 фев 2015, 10:22

Скорее всего так и есть, но почему? Ведь я наполняю массив, который объявлен в классе Api и его не очищаю, поэтому мне интересно, каким образом он очищается?

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Неожиданный null в результате

Сообщение Mikhail_dev » 05 фев 2015, 10:30

Вы сначала покажите каким образом создаётся этот API класс. Он не синглтон и ссылка data не статическая, поэтому он может просто создаться как новый объект по тому же сценарию что указал klblk

Lemme
Сообщения: 16
Зарегистрирован: 29 янв 2015, 23:38

Re: Неожиданный null в результате

Сообщение Lemme » 05 фев 2015, 10:35

Код: Выделить всё

   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Api api = new Api(this);

        String[] from = {api.ATTRIBUTE_NAME_IMAGE, api.ATTRIBUTE_NAME_TITLE, api.ATTRIBUTE_NAME_DATE};
        int[] to = {R.id.imageView, R.id.title, R.id.date};

        ArrayList<Map<String, Object>> posts =  api.getPosts();

        System.out.println(posts);
        SimpleAdapter adapter = new SimpleAdapter(this, posts, R.layout.item, from, to);

        lv = (ListView) findViewById(R.id.listView);
        lv.setAdapter(adapter);
    }
Как мне кажется

Создаем экземпляр класса. Так как в конструкторе метод getPosts() не вызывается, то data == null
Api api = new Api(this);
Теперь вызываем метод getPosts, так как он возвращает data, то результат записываем в переменную posts
ArrayList<Map<String, Object>> posts = api.getPosts();


вроде все по порядку...

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Неожиданный null в результате

Сообщение Mikhail_dev » 05 фев 2015, 10:53

Вы не понимаете что такое асихронные запросы. Я проставил очередность вызова вашего кода
[syntax=java5]
public ArrayList<Map<String, Object>> getPosts() {
//1 ВХОД В МЕТОД.
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://indpre.ru/test/", null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray posts = response.getJSONArray("posts");
data = new ArrayList<>(posts.length());
//3 ИНИЦИАЛИЗАЦИЯ "data" (ТОЛЬКО ТЕПЕРЬ СТАЛА НЕ NULL) И ЕЁ НАПОЛНЕНИЕ
...
}

} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {

}
});
//2 СОЗДАЛИ ОБЪЕКТ jsonObjectRequest И ПРИШЛИ СЮДА. data ПО ПРЕЖНЕМУ NULL
queue.add(jsonObjectRequest);
return data;
}
[/syntax]

Lemme
Сообщения: 16
Зарегистрирован: 29 янв 2015, 23:38

Re: Неожиданный null в результате

Сообщение Lemme » 05 фев 2015, 11:00

Mikhail_dev, большое спасибо за подробное объяснение, проставил везде отметки и понял как он работает.

Я так понимаю, что getPosts не должен ничего возвращать,а должен лишь наполнить data, а уже потом вызывать data?

Код: Выделить всё

Api api = new Api(this);
api.getPosts();
api.data; // тут заполненный массив

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Неожиданный null в результате

Сообщение Mikhail_dev » 05 фев 2015, 11:22

Я не совсем понял вас.
Здесь надо делать через слушатели(Listener), и возвращать ответ именно в методе onResponse.

Lemme
Сообщения: 16
Зарегистрирован: 29 янв 2015, 23:38

Re: Неожиданный null в результате

Сообщение Lemme » 05 фев 2015, 11:24

Mikhail_dev, еще раз спасибо, буду разбираться со слушателями)

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Неожиданный null в результате

Сообщение Mikhail_dev » 05 фев 2015, 11:31

Слушатели - это интерфейсы и они относятся к инкапсуляции. В общем это java, а не Android. Так что ищите инфу по Java. Почитайте Хорстманна первый том.

Lemme
Сообщения: 16
Зарегистрирован: 29 янв 2015, 23:38

Re: Неожиданный null в результате

Сообщение Lemme » 05 фев 2015, 11:39

Mikhail_dev, да-да, по java и ищу, точнее, уже нашел)

Ответить