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()

这里有几件事你可以做得更好。但是您的主要问题是您正在执行异步任务(后台任务)并且没有处理正确的回调。

接下来会发生什么:

  1. 异步任务开始。
  2. 你睡了 3 秒(这可能是为了在代码继续之前尝试让异步完成。)
  3. 异步任务可能在 3 秒内未完成。
  4. 您尝试解析尚未收到的JSON。
  5. 这会抛出一个空指针。

现在,当崩溃时,异步任务仍在运行并完成。我不确定您是否保存此 JSON 然后它在完成时变得可读并在第二次可用,或者第二次任务可能会在 3 秒内完成。

你应该做什么

  1. 异步任务开始。
  2. 让线程休眠。
  3. 在异步任务中 onPostExecute 有一个回调到你的主线程。
  4. 从任务中获得return回调JSON。
  5. 现在解析你将拥有的 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);
}