U
U
uaSaint2014-02-11 14:36:40
Android
uaSaint, 2014-02-11 14:36:40

Android + json == NullPointerException

Actually, I apologize for the probably not correct question, since the reason for NullPointerException is known to me, but my level of knowledge does not allow me to solve it. It's been a week, I don't understand.
The task is to get json from a request to the open photos.search of the vk.com service (but this is not particularly important here). I need to parse json and put everything into a structure accessible from outside (it doesn't matter which one, but I like ArrayList>).
How I do it now:

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()));
    }
}

Commented out 2 lines (setImageUrl and setText) - just checked that everything works and is received / given. Now I use Valley (I tried AndroidAsyncHttpClient / AsyncTask and other standard tools - everything works, but the problem is the same.)
And the problem is in the last line: Log.i(LOG_TAG, String.valueOf(arrayList.size())); Which throws this exception (again, the meaning of the line is not important, any access to the variable gives an exception). I understand that the reason is that by executing in a loop: arrayList.add(map); inside the onResponse methodI am doing something wrong. It also seems to me that my problem is related to the basics of OOP and this is sad. But for a long time I can not understand what is happening and find a solution. How can I return a value from a method that returns nothing, and in another thread should work. For the life of me I can't understand this java. And all my knowledge in python is useless here.
Direct on the right path?
ps Of course, I can go the other way and just put these lines in the base. There is no problem here, but I would not want to choose some solution just because I don’t know how otherwise.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
B
bimeg, 2014-02-11
@uaSaint

1) Volley calls the Listener on the main thread (and not on the worker thread that made the request)
2) You blocked the main thread with a wait loop and therefore Volley could not call your listener (due to the peculiarities of the main thread). This means that there will never be an exit from the cycle - live-lock.
3) Because onResponse is already on the main thread, then no one bothers to display the result in the GUI in the same place.
4) Parsing json on the main thread is very bad.

F
FoxInSox, 2014-02-11
@FoxInSox

Before putting something into the list, you need to create it:

ArrayList<HashMap<String, String>> arrayList = new ArrayList<HashMap<String, String>>();

U
uaSaint, 2014-02-11
@uaSaint

I added:

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();
}

as a result, in the log (last line):
(map): [-61794185, <here_url>, <here_text>]
arrayList: 271

i.e. 271 values ​​came into it ... the problem is that they are deleted at the moment when I called Log.d(LOG_TAG, String.valueOf(arrayList.size())); arrayList is empty...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question