@uaSaint

Android + json == NullPointerException

Собственно извиняюсь за наверно не корректный вопрос, поскольку причина NullPointerException мне известна, вот только мой уровень знаний не позволяет решить ее. Уже неделю убил, не понимаю.
Задача - получаю json из запроса к открытому photos.search сервиса vk.com (но это тут не особо важно). Мне нужно разобрать json и сложить все в доступную из вне структуру (не важно какую, но мне нравится ArrayList>).
Как я это сейчас делаю:
public class MainActivity extends ActionBarActivity {

    private static final String LOG_TAG = "MainActivity";
    private static final String PHOTO_URL = "https://api.vk.com/method/photos.search?q=girls&count=1000&radius=5000&v=5.7";
    private static final int PHOTO_POSITION = 0; //temporary field

    ArrayList<HashMap<String, String>> arrayList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final SmartImageView myImage = (SmartImageView) findViewById(R.id.my_image);
        final TextView myText = (TextView) findViewById(R.id.textView);



        RequestQueue queue = Volley.newRequestQueue(this);
        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, PHOTO_URL,
                null, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                JSONObject jsonObject;
                try {
                    jsonObject = new JSONObject(String.valueOf(response));
                    JSONObject jsonResult = jsonObject.getJSONObject("response");
                    JSONArray jArray = jsonResult.getJSONArray("items");

                    for (int i = 0; i < jArray.length(); i++) {
                        HashMap<String, String> map = new HashMap<String, String>();
                        // Retrieve JSON Objects
                        map.put("photo_604", jArray.getJSONObject(i).getString("photo_604"));
                        map.put("text", jArray.getJSONObject(i).getString("text"));
                        map.put("owner_id", jArray.getJSONObject(i).getString("owner_id"));
                        // Set the JSON Objects into the array
                        arrayList.add(map);
                    }
                    /*myImage.setImageUrl(jArray.getJSONObject(PHOTO_POSITION).getString("photo_604"));
                    myText.setText(jArray.getJSONObject(PHOTO_POSITION).getString("text"));*/

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(LOG_TAG, "onErrorResponse");
            }
        });

        queue.add(jsObjRequest);

        Log.i(LOG_TAG, String.valueOf(arrayList.size()));
    }
}

Закоментированные 2 строчки (setImageUrl и setText)- просто проверял, что все работает и получается / отдается. Сейчас использую Valley(пробывал AndroidAsyncHttpClient / AsyncTask и другие стандартные средства - все работает но проблема та же.)
И проблема в последней строчке: Log.i(LOG_TAG, String.valueOf(arrayList.size())); Которая и выбрасывает это исключение(опять же смысл строки не важен, любое обращение к переменной дает исключение). Я понимаю, что причина в том, что выполняя в цикле: arrayList.add(map);внутри метода onResponse я делаю что то не так. Еще мне кажется, что моя проблема связанна с основами ООП и это печально. Но я уже достаточно давно не могу понять, что происходит и найти решение. Как мне вернуть значение из метода, который ничего не возвращает, еще и в другом потоке должен работать. Хоть убей не могу понять эту java. А все мои знания в python тут бесполезны.

Направите на путь истинный?

p.s. Я конечно могу пойти другим путем и просто положить эти строки в базу. Тут нет проблемы, но не хотелось бы выбирать какое-то решение только потому, что иначе я не умею.
  • Вопрос задан
  • 3724 просмотра
Решения вопроса 1
@bimeg
1) Volley вызывает Listener на главном потоке (а не на worker потоке, который делал запрос)
2) Вы циклом ожидания заблокировали главный поток и поэтому Volley не смог вызвать ваш листнер (изза особенностей работы главного потока). А значит выхода из цикла не будет никогда - live-lock.
3) Т.к. onResponse уже на главном потоке, то никто не мешает там же отобразить результат в ГУИ.
4) Парсить жсон на главном потоке очень плохо.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@FoxInSox
Перед тем как что-то ложить в список его нужно создать:
ArrayList<HashMap<String, String>> arrayList = new ArrayList<HashMap<String, String>>();
Ответ написан
@uaSaint Автор вопроса
Я добавил:
try{
     arrayList.add(map);
     Log.d(LOG_TAG, "(map): " + map.values());
     Log.d(LOG_TAG, "arrayList: " + String.valueOf(arrayList.size()));
}catch (Exception e) {
     Log.e(LOG_TAG, "arrayList.add(map): ERROR");
     e.printStackTrace();
}

в результате в логе(последняя строка):
(map): [-61794185, <тут_url>, <тут_текст>]
arrayList: 271

т. е. в него пришло 271 значение... проблема в том, что они удаляются и в момент, когда я вызывал Log.d(LOG_TAG, String.valueOf(arrayList.size())); arrayList пуст...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы