简体   繁体   English

JSON API Android解析教程

[英]JSON API Android Parsing tutorial

So I've been following [this tutorial][1] and watched through it and written all the code (except for a few changes to suit my needs) and whenever I launch the app using an emulator it will display "Progress start" with the loading animation underneath it (like it's supposed to) then it crashes. 因此,我一直遵循[本教程] [1]并仔细阅读并编写了所有代码(除了一些更改以满足我的需要),每当我使用模拟器启动应用程序时,它都会显示“进度开始”它下面的加载动画(应该是这样)然后崩溃。 I messed around with it for a couple of minutes but couldn't figure out how to fix it since I'm still pretty new to Android development. 我花了几分钟时间弄乱了它,但由于我还是Android开发的新手,所以不知道如何解决它。

Error log: 错误日志:

    08-03 17:41:39.293  10235-10255/? E/JSON Parser﹕ Error parsing data org.json.JSONException: Value {"address":"mc.hypixel.net","port":25565,"online":true,"players":{"max":35053,"online":22162,"sample":[]},"motd":"§aHypixel Network\n§c§l2 NEW GAMES! §bPixel Painters §e+ §bMega Skywars","version":{"name":"Hypixel BungeeCord","protocol":4},"ping":203} of type org.json.JSONObject cannot be converted to JSONArray
08-03 17:41:39.295  10235-10255/? E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    Process: in.untie.hypixelmobile, PID: 10235
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:304)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference
            at in.untie.hypixelmobile.MainActivity$ProgressTask.doInBackground(MainActivity.java:80)
            at in.untie.hypixelmobile.MainActivity$ProgressTask.doInBackground(MainActivity.java:40)
            at android.os.AsyncTask$2.call(AsyncTask.java:292)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
08-03 17:41:41.007  10235-10235/? E/WindowManager﹕ android.view.WindowLeaked: Activity in.untie.hypixelmobile.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{a3a3b8a V.E..... R......D 0,0-1026,348} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
            at android.app.Dialog.show(Dialog.java:298)
            at in.untie.hypixelmobile.MainActivity$ProgressTask.onPreExecute(MainActivity.java:55)
            at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:591)
            at android.os.AsyncTask.execute(AsyncTask.java:539)
            at in.untie.hypixelmobile.MainActivity.onCreate(MainActivity.java:37)
            at android.app.Activity.performCreate(Activity.java:5990)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

MainActivity.java MainActivity.java

   package in.untie.hypixelmobile;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

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

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

public class MainActivity extends ListActivity {

    private Context context;
    private static String url = "http://api.razex.de/server/status/mc.hypixel.net:25565";

    private static final String PMAX = "Max";
    private static final String PCURRENT = "Current";
    private static final String PING = "Ping";

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

    ListView lv;

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

        new ProgressTask(MainActivity.this).execute();
    }

    private class ProgressTask extends AsyncTask<String, Void, Boolean> {

        private ProgressDialog dialog;
        private ListActivity activity;
        private Context context;

        public ProgressTask(ListActivity activity) {
            this.activity = activity;
            context = activity;
            dialog = new ProgressDialog(context);
        }

        @Override
        protected void onPreExecute() {
            this.dialog.setMessage("Progress start");
            this.dialog.show();
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if (dialog.isShowing()) {
                dialog.dismiss();
            }

            ListAdapter adapter = new SimpleAdapter(context, jsonlist,
                    R.layout.list_item, new String[]{PMAX, PCURRENT, PING}
                        , new int[]{R.id.ping, R.id.max, R.id.current});

            setListAdapter(adapter);

            lv = getListView();

        }

        @Override
        protected Boolean doInBackground(String... params) {

            JSONParser jParser = new JSONParser();
            JSONArray json = jParser.getJSONFromURL(url);

            for(int i = 0; i < json.length(); i++) {

                try {

                    JSONObject c = json.getJSONObject(i);
                    String ping = c.getString("ping");
                    String pcurrent = c.getString("online");
                    String pmax = c.getString("max");

                    HashMap<String, String> map = new HashMap<String, String>();

                    map.put(PING, ping);
                    map.put(PCURRENT, pcurrent);
                    map.put(PMAX, pmax);
                    jsonlist.add(map);

                } catch(JSONException e) {

                    e.printStackTrace();

                }
            }
            return false;
        }
    }
}

JSONParser.java JSONParser.java

package in.untie.hypixelmobile;

import android.util.Log;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class JSONParser {

    static InputStream iStream = null;
    static JSONObject jarray = null;
    static String json = "";

    public JSONParser() {

    }

    public JSONObject getJSONFromURL(String url) {

        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);

        try {

            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();

            if(statusCode == 200) {

                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));

                String line;

                while((line = reader.readLine()) != null) {
                    builder.append(line);
                }

            } else {
                Log.e("==>", "Failed to download file");
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            jarray = new JSONObject(builder.toString());
        } catch(JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        return jarray;

    }

}

change 更改

JSONArray json = jParser.getJSONFromURL(url);

to

JSONObject json = jParser.getJSONFromURL(url);

The

for(int i = 0; i < json.length(); i++) {

with

JSONObject c = json.getJSONObject(i);

loop is also irrelevant. 循环也无关紧要。

Reason : You are not getting JSON Array in response, you are getting just object. 原因:您没有得到JSON Array作为响应,只是得到了对象。 As a quick rule : between { is JSONObject, between [ is JSONArray (where you would use loop to cycle through). 快速规则: {之间是JSONObject,之间[是JSONArray(您将使用循环循环通过的位置)。 Your only array there is sample but there is nothing inside it. 您唯一的数组中有样本,但其中没有任何内容。

Also note you have players object inside main object! 另请注意,您在主要对象内有玩家对象! You need to get object players before accessing the max 您需要先获得对象玩家,然后才能访问最高

EDIT : 编辑:

        JSONParser jParser = new JSONParser();
        JSONObject json = jParser.getJSONFromURL(url);

        //for loop useless

            try {

                //JSONObject c = json.getJSONObject(i); is useless. you are not getting i-th object of array because there is no loop and no array

                String ping = json.getString("ping");
                String pcurrent = json.getString("online"); //if returns true/false use getBoolean instead of getString?

                //max is inside of another object. get it first to get to it.
                JSONObject playersObject = json.getJSONObject("players");
                String pmax = playersObject.getString("max");

                HashMap<String, String> map = new HashMap<String, String>();

                map.put(PING, ping);
                map.put(PCURRENT, pcurrent);
                map.put(PMAX, pmax);
                jsonlist.add(map);

            } catch(JSONException e) {

                e.printStackTrace();

            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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