json 对象上的 NullPointerException
NullPointerException on json object
为什么我 运行 我的应用程序总是收到 NullPointerException?每次我启动我的 genymotion 模拟器,然后第一次 运行 应用程序时,它会崩溃,但第二次 运行 我的应用程序运行顺利。我不知道为什么它每次都发生在第一个 运行。
这是我的初始屏幕,它从 RetrieveGamesBGTask 中检索 JSON 对象:
public class Splash extends Activity {
RetrieveGamesBGTask retrieveGamesBGTask;
String json_string;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread thread = new Thread(){
@Override
public void run() {
try {
retrieveGamesBGTask = new RetrieveGamesBGTask();
retrieveGamesBGTask.execute();
sleep(3000);
Intent intent = new Intent(getApplication(), Games.class);
intent.putExtra("json_data", json_string);
intent.putExtra("json_data", retrieveGamesBGTask.getResult());
startActivity(intent);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
这是下一个应用程序,它每次在第一个 运行 时崩溃:
retrieveGamesBGTask = new RetrieveGamesBGTask();
retrieveGamesBGTask.execute();
Intent intent = this.getIntent();
if (intent != null) {
json_string = intent.getStringExtra("json_data");
}
try {
if (jsonObject == null) {
jsonObject = new JSONObject(json_string);
jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
String teamone, teamonepts, teamtwo, teamtwopts, s_name, s_gender;
while (count < jsonArray.length()) {
JSONObject JO = jsonArray.getJSONObject(count);
teamone = JO.getString("teamone");
teamonepts = JO.getString("teamonepts");
teamtwo = JO.getString("teamtwo");
teamtwopts = JO.getString("teamtwopts");
s_name = JO.getString("s_name");
s_gender = JO.getString("s_gender");
Downloader downloader = new Downloader(teamone, teamonepts, teamtwo, teamtwopts, s_name, s_gender);
gamesAdapter.add(downloader);
count++;
}
} else {
Toast.makeText(this, "JSON is null", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
这是我的 RetrieveGamesBGTask
class RetrieveGamesBGTask extends AsyncTask<Void, Void, String> {
String json_result, json_string;
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(Config.URL_GAMES);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputstream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputstream));
StringBuilder stringBuilder = new StringBuilder();
while ((json_string = bufferedReader.readLine()) != null) {
stringBuilder.append(json_string + "\n");
}
bufferedReader.close();
inputstream.close();
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String result) {
Log.d("haha", "hehe");
json_result = result;
}
public String getResult() {
return json_result;
}
这是我的logcat:
FATAL EXCEPTION: main
Process: com.example.aaa.bbb, PID: 5680
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.aaa.bbb/com.example.aaa.bbb.Games}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
嗯,错误很明显:
Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
所以你在某个地方调用了一个未初始化的字符串的长度。这不在您发布的代码中。 (仅 jsonArray.length()
)
这里有几件事你可以做得更好。但是您的主要问题是您正在执行异步任务(后台任务)并且没有处理正确的回调。
接下来会发生什么:
- 异步任务开始。
- 你睡了 3 秒(这可能是为了在代码继续之前尝试让异步完成。)
- 异步任务可能在 3 秒内未完成。
- 您尝试解析尚未收到的JSON。
- 这会抛出一个空指针。
现在,当崩溃时,异步任务仍在运行并完成。我不确定您是否保存此 JSON 然后它在完成时变得可读并在第二次可用,或者第二次任务可能会在 3 秒内完成。
你应该做什么
- 异步任务开始。
- 不不让线程休眠。
- 在异步任务中
onPostExecute
有一个回调到你的主线程。
- 从任务中获得return回调JSON。
- 现在解析你将拥有的 JSON,如果调用本身确实成功的话。
要实现这个请看这里https://developer.android.com/training/best-background.html
它应该提供足够的信息来稳定这段代码。
另一种将意图置于 post 执行中的方法。
在你的 Activity 的 onCreate
方法中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
new RetrieveGamesBGTask(Splash.this).execute();
}
现在在您的 RetrieveGamesBGTask's onPostExecute
方法中
@Override
protected void onPostExecute(String result) {
Log.d("haha", "hehe");
json_result = result;
Intent intent = new Intent(context, Games.class);
intent.putExtra("json_data", json_string);
intent.putExtra("json_data",json_result);
context.startActivity(intent);
}
为什么我 运行 我的应用程序总是收到 NullPointerException?每次我启动我的 genymotion 模拟器,然后第一次 运行 应用程序时,它会崩溃,但第二次 运行 我的应用程序运行顺利。我不知道为什么它每次都发生在第一个 运行。
这是我的初始屏幕,它从 RetrieveGamesBGTask 中检索 JSON 对象:
public class Splash extends Activity {
RetrieveGamesBGTask retrieveGamesBGTask;
String json_string;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread thread = new Thread(){
@Override
public void run() {
try {
retrieveGamesBGTask = new RetrieveGamesBGTask();
retrieveGamesBGTask.execute();
sleep(3000);
Intent intent = new Intent(getApplication(), Games.class);
intent.putExtra("json_data", json_string);
intent.putExtra("json_data", retrieveGamesBGTask.getResult());
startActivity(intent);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
这是下一个应用程序,它每次在第一个 运行 时崩溃:
retrieveGamesBGTask = new RetrieveGamesBGTask();
retrieveGamesBGTask.execute();
Intent intent = this.getIntent();
if (intent != null) {
json_string = intent.getStringExtra("json_data");
}
try {
if (jsonObject == null) {
jsonObject = new JSONObject(json_string);
jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
String teamone, teamonepts, teamtwo, teamtwopts, s_name, s_gender;
while (count < jsonArray.length()) {
JSONObject JO = jsonArray.getJSONObject(count);
teamone = JO.getString("teamone");
teamonepts = JO.getString("teamonepts");
teamtwo = JO.getString("teamtwo");
teamtwopts = JO.getString("teamtwopts");
s_name = JO.getString("s_name");
s_gender = JO.getString("s_gender");
Downloader downloader = new Downloader(teamone, teamonepts, teamtwo, teamtwopts, s_name, s_gender);
gamesAdapter.add(downloader);
count++;
}
} else {
Toast.makeText(this, "JSON is null", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
这是我的 RetrieveGamesBGTask
class RetrieveGamesBGTask extends AsyncTask<Void, Void, String> {
String json_result, json_string;
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(Config.URL_GAMES);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputstream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputstream));
StringBuilder stringBuilder = new StringBuilder();
while ((json_string = bufferedReader.readLine()) != null) {
stringBuilder.append(json_string + "\n");
}
bufferedReader.close();
inputstream.close();
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String result) {
Log.d("haha", "hehe");
json_result = result;
}
public String getResult() {
return json_result;
}
这是我的logcat:
FATAL EXCEPTION: main
Process: com.example.aaa.bbb, PID: 5680
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.aaa.bbb/com.example.aaa.bbb.Games}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
嗯,错误很明显:
Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
所以你在某个地方调用了一个未初始化的字符串的长度。这不在您发布的代码中。 (仅 jsonArray.length()
)
这里有几件事你可以做得更好。但是您的主要问题是您正在执行异步任务(后台任务)并且没有处理正确的回调。
接下来会发生什么:
- 异步任务开始。
- 你睡了 3 秒(这可能是为了在代码继续之前尝试让异步完成。)
- 异步任务可能在 3 秒内未完成。
- 您尝试解析尚未收到的JSON。
- 这会抛出一个空指针。
现在,当崩溃时,异步任务仍在运行并完成。我不确定您是否保存此 JSON 然后它在完成时变得可读并在第二次可用,或者第二次任务可能会在 3 秒内完成。
你应该做什么
- 异步任务开始。
- 不不让线程休眠。
- 在异步任务中
onPostExecute
有一个回调到你的主线程。 - 从任务中获得return回调JSON。
- 现在解析你将拥有的 JSON,如果调用本身确实成功的话。
要实现这个请看这里https://developer.android.com/training/best-background.html
它应该提供足够的信息来稳定这段代码。
另一种将意图置于 post 执行中的方法。
在你的 Activity 的 onCreate
方法中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
new RetrieveGamesBGTask(Splash.this).execute();
}
现在在您的 RetrieveGamesBGTask's onPostExecute
方法中
@Override
protected void onPostExecute(String result) {
Log.d("haha", "hehe");
json_result = result;
Intent intent = new Intent(context, Games.class);
intent.putExtra("json_data", json_string);
intent.putExtra("json_data",json_result);
context.startActivity(intent);
}