因此,我一直遵循[本教程] [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();
}
关于java - JSON API Android解析教程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31798952/