简体   繁体   中英

Retrieve and parse JSON from multiple URLs and add to listview

I started learning android a week ago and decided to write a simple android application for a website bhooka.in . I used koush/ion api to retrieve json data from the url.

Here's the problem - I have a single JSON file, containing multiple JSON URLs. Now I tried to retrieve all the JSONs in a for loop, but that doesn't seem to work. Here's the code:

Future<JsonObject> loading;

private void load() {
    // don't attempt to load more if a load is already in progress
    if (loading != null && !loading.isDone() && !loading.isCancelled())
        return;

    // load the tweets
    String url = "http://bhooka.in/web_services_json_helper.php?mode=fetch_locations&user_agent=in.bhooka.bhooka&city_id=4";
    loading = Ion.with(this)
            .load(url)
            .asJsonObject()
            .setCallback(new FutureCallback<JsonObject>() {
                @Override
                public void onCompleted(Exception e, JsonObject result) {
                    // this is called back onto the ui thread, no Activity.runOnUiThread or Handler.post necessary.
                    if (e != null) {
                        Toast.makeText(getView().getContext(), "Error loading information", Toast.LENGTH_LONG).show();
                        return;
                    }
                    JsonArray locationsList = result.getAsJsonArray("locations");
                    // add the tweets
                    for (int i = 0; i < locationsList.size(); i++) {
                        try {
                            JsonObject temp = Ion.with(getView().getContext())
                                    .load("http://bhooka.in/web_services_json_helper.php?mode=fetch_loc_info&user_agent=in.bhooka.bhooka&loc_id=" + locationsList.get(i).getAsJsonObject().get("post_id").getAsString())
                                    .asJsonObject().get();
                            placeArrayAdapter.add(temp.get("loc_info").getAsJsonObject());
                        }
                        catch (Exception ex)
                        {
                            ex.printStackTrace();
                        }

                                /* tried this approach - but it doesn't work
                                .setCallback(new FutureCallback<JsonObject>() {
                                    @Override
                                    public void onCompleted(Exception e, JsonObject result) {
                                        // this is called back onto the ui thread, no Activity.runOnUiThread or Handler.post necessary.
                                        if (e != null) {
                                            Toast.makeText(getView().getContext(), "Error loading information", Toast.LENGTH_LONG).show();
                                            return;
                                        }
                                        placeArrayAdapter.add(result.get("loc_info").getAsJsonObject());
                                    }
                                });*/
                    }
                }
            });
}

The application opens up and then just freezes. I've also tried the asynchronous approach using callbacks, but it just shows up one or two entries in the listview and then it crashes. Could somebody please tell me what I'm doing wrong?

Thanks a lot.

EDIT: As suggested, here's the logcat:

07-14 17:02:11.851  20332-20332/? D/dalvikvm﹕ Late-enabling CheckJNI
07-14 17:02:11.867  20332-20338/? D/dalvikvm﹕ Debugger has detached; object registry had 1 entries
07-14 17:02:12.206  20332-20332/? I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8610_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-14 17:02:12.244  20332-20332/? D/OpenGLRenderer﹕ Enabling debug mode 0
07-14 17:02:14.469  20332-20364/in.bhooka.bhooka D/dalvikvm﹕ Trying to load lib /data/app-lib/in.bhooka.bhooka-2/libgmscore.so 0x41d995f0
07-14 17:02:14.470  20332-20364/in.bhooka.bhooka E/dalvikvm﹕ dlopen("/data/app-lib/in.bhooka.bhooka-2/libgmscore.so") failed: dlopen failed: library "/data/app-lib/in.bhooka.bhooka-2/libgmscore.so" not found
07-14 17:02:14.470  20332-20364/in.bhooka.bhooka E/ProviderInstaller﹕ Unable to load native code from /data/app-lib/in.bhooka.bhooka-2/libgmscore.so
07-14 17:02:14.470  20332-20364/in.bhooka.bhooka D/dalvikvm﹕ Trying to load lib /data/app-lib/com.google.android.gms-2/libgmscore.so 0x41d995f0
07-14 17:02:14.472  20332-20364/in.bhooka.bhooka D/dalvikvm﹕ Added shared lib /data/app-lib/com.google.android.gms-2/libgmscore.so 0x41d995f0
07-14 17:02:14.472  20332-20364/in.bhooka.bhooka D/dalvikvm﹕ No JNI_OnLoad found in /data/app-lib/com.google.android.gms-2/libgmscore.so 0x41d995f0, skipping init
07-14 17:02:14.474  20332-20364/in.bhooka.bhooka E/ProviderInstaller﹕ libgmscore version mismatch (0 vs. 7574)
07-14 17:02:14.474  20332-20364/in.bhooka.bhooka W/IonConscrypt﹕ Conscrypt initialization failed.
07-14 17:02:44.955  20332-20364/in.bhooka.bhooka D/dalvikvm﹕ GC_FOR_ALLOC freed 3066K, 29% free 7930K/11072K, paused 37ms, total 47ms
07-14 17:02:45.008  20332-20332/in.bhooka.bhooka D/AndroidRuntime﹕ Shutting down VM
07-14 17:02:45.008  20332-20332/in.bhooka.bhooka W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x415dad40)
07-14 17:02:45.010  20332-20332/in.bhooka.bhooka E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: in.bhooka.bhooka, PID: 20332
    java.lang.NullPointerException
            at in.bhooka.bhooka.MainActivity$1.onCompleted(MainActivity.java:73)
            at in.bhooka.bhooka.MainActivity$1.onCompleted(MainActivity.java:67)
            at com.koushikdutta.async.future.SimpleFuture.handleCallbackUnlocked(SimpleFuture.java:107)
            at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:141)
            at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:124)
            at com.koushikdutta.ion.IonRequestBuilder$1.run(IonRequestBuilder.java:244)
            at com.koushikdutta.async.AsyncServer$RunnableWrapper.run(AsyncServer.java:57)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

instead use retrofit and jackson converter to get the locations . It would really simply your code since code is really complex. These are the best combination to deal with urls

When you want to add items to an ListView/adapter, you have to do this in the main-thread. You can use a Handler for that:

In your main-thread

Handler handler = new Handler();

And when you need to execute something on the main-thread

handler.post(new Runnable() {
    @Override
    public void run() {
        placeArrayAdapter.add(temp.get("loc_info").getAsJsonObject());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM