Skip to main content
 首页 » 编程设计

java之JSON API Android解析教程

2025年05月04日317jpfss

因此,我一直遵循[本教程] [1]并仔细阅读并编写了所有代码(除了一些更改以满足我的需要),每当我使用仿真器启动应用程序时,它都会显示“进度开始”它下面的加载动画(应该是这样)然后崩溃。我花了几分钟时间弄乱了它,但由于我还是Android开发的新手,所以不知道如何解决它。

错误日志:

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

请您参考如下方法:

更改

JSONArray json = jParser.getJSONFromURL(url); 


JSONObject json = jParser.getJSONFromURL(url); 


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


JSONObject c = json.getJSONObject(i); 

循环也无关紧要。

原因:您没有得到JSON Array作为响应,只是得到了对象。快速规则是: {是JSONObject, [是JSONArray(您可以使用循环来循环)。唯一的数组是 示例,但其中没有任何内容。

还要注意,您在主对象中有 播放器对象!您需要先获得对象 玩家,然后才能访问 max

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