java.lang.NullPointerException:尝试在null对象引用上调用虚方法

时间:2016-01-17 19:05:17

标签: java android nullpointerexception

所以我正在开发一个使用CardView和RecycleView显示JSON数据的个人应用程序,但是我经常得到这个NullPointerException,我不知道应该如何调试这个,我真的可以使用一些帮助。 / p>

这些是我得到的错误

    {java.lang.RuntimeException: Unable to start activity ComponentInfo{com.brokenbroadcast.nba_project/com.brokenbroadcast.nba_project.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.brokenbroadcast.nba_project.NBA.getGameList()' on a null object reference
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3149)
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
  at android.app.ActivityThread.access$1000(ActivityThread.java:197)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1681)
  at android.os.Handler.dispatchMessage(Handler.java:102)
  at android.os.Looper.loop(Looper.java:145)
  at android.app.ActivityThread.main(ActivityThread.java:6891)
  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:1404)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
  at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.brokenbroadcast.nba_project.NBA.getGameList()' on a null object reference
  at com.brokenbroadcast.nba_project.MainActivity.onCreate(MainActivity.java:52)
  at android.app.Activity.performCreate(Activity.java:6550)
  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1120)
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3102)
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) 
  at android.app.ActivityThread.access$1000(ActivityThread.java:197) 
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1681) 
  at android.os.Handler.dispatchMessage(Handler.java:102) 
  at android.os.Looper.loop(Looper.java:145) 
  at android.app.ActivityThread.main(ActivityThread.java:6891) 
  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:1404) 
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

根据我的理解,我的代码在MainActivity.java:52有问题。 这是我的MainActivity.java

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

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

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

private List<Game> gameList;
private NBA mNBA;
public static final String TAG = MainActivity.class.getSimpleName();
public static final String mScoreboardUrl = "http://data.nba.com/5s/json/cms/noseason/scoreboard/20160116/games.json";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.content_main);
    RecyclerView recList = (RecyclerView) findViewById(R.id.cardList);
    recList.setHasFixedSize(true);
    LinearLayoutManager llm = new LinearLayoutManager(this);
    llm.setOrientation(LinearLayoutManager.VERTICAL);
    recList.setLayoutManager(llm);
    gameList = new ArrayList<Game>();
    setUpGames();

    GameAdapter ca = new GameAdapter(mNBA.getGameList());
    recList.setAdapter(ca);
}



private void setUpGames() {
    if (isNetworkAvailable()) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(mScoreboardUrl).build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                alertUserAboutError();
            }

            @Override
            public void onResponse(Response response) throws IOException {
                try {
                    String jsonData = response.body().string();
                    if (response.isSuccessful()) {
                        mNBA = parseNBADetails(jsonData);
                    } else {
                        alertUserAboutError();
                    }
                } catch (IOException e) {
                } catch (JSONException j) {
                }
            }
        });
    } else {
        Toast.makeText(this, getString(R.string.network_unavailable_message),
                Toast.LENGTH_LONG).show();
    }
}


private void alertUserAboutError() {
    AlertDialogFragment dialog = new AlertDialogFragment();
    dialog.show(getFragmentManager(), "error_dialog");
}

private boolean isNetworkAvailable() {
    ConnectivityManager manager = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();
    boolean isAvailable = false;
    if (networkInfo != null && networkInfo.isConnected()) {
        isAvailable = true;
    }

    return isAvailable;

}

private NBA parseNBADetails(String jsonData) throws JSONException {

    NBA nba = new NBA();
    nba.setGameList(parseGames(jsonData));

    return nba;
}

private List<Game> parseGames(String jsonData) throws JSONException {
    JSONObject sports_content = new JSONObject(jsonData);
    JSONObject schedule = sports_content.getJSONObject("sports_content");
    JSONObject gameArray = schedule.getJSONObject("games");
    JSONArray data = gameArray.getJSONArray("game");

    List<Game> gameList = new ArrayList<Game>();
    for (int i = 0; i < data.length(); i++) {
        Game game = new Game();
        JSONObject jsonGame = data.getJSONObject(i);

        JSONObject jsonVisitor = jsonGame.getJSONObject("visitor");
        game.setVisitorTeamName(jsonVisitor.getString("nickname"));
        game.setVisitorScore(jsonVisitor.getInt("score"));
        game.setVisitorTeamLocation(jsonVisitor.getString("city"));

        JSONObject jsonHome = jsonGame.getJSONObject("home");
        game.setHomeTeamLocation(jsonHome.getString("city"));
        game.setHomeTeamName(jsonHome.getString("nickname"));
        game.setHomeScore(jsonHome.getInt("score"));

        Log.i(TAG, game.getHomeScore() + "");

        gameList.add(game);
    }
    return gameList;
}
}

这是我的班级NBA.java

public class NBA {
private List<Game> mGameList;

public List<Game> getGameList() {
    return mGameList;
}

public void setGameList(List<Game> gameList) {
    mGameList = gameList;
}
}

这是我的Game.java

public class Game {


    private int mHomeScore;
    private int mVisitorScore;
    private String mHomeTeamLocation;
    private String mHomeTeamName;
    private String mVisitorTeamLocation;
    private String mVisitorTeamName;


    public String getHomeTeamLocation() {
        return mHomeTeamLocation;
    }

    public Game(){}

    public void setHomeTeamLocation(String homeTeamLocation) {
        mHomeTeamLocation = homeTeamLocation;
    }

    public String getHomeTeamName() {
        return mHomeTeamName;
    }

    public void setHomeTeamName(String homeTeamName) {
        this.mHomeTeamName = homeTeamName;
    }

    public String getVisitorTeamLocation() {
        return mVisitorTeamLocation;
    }

    public void setVisitorTeamLocation(String visitorTeamLocation) {
        mVisitorTeamLocation = visitorTeamLocation;
    }

    public String getVisitorTeamName() {
        return mVisitorTeamName;
    }

    public void setVisitorTeamName(String visitorTeamName) {
        mVisitorTeamName = visitorTeamName;
    }


    public String getTitle() {
        return getHomeTeam() + " vs. " + getVisitorTeam();
    }

    public String getHomeTeam() {

        return mHomeTeamLocation+" " +mHomeTeamName;
    }

    public String getVisitorTeam() {
        return mVisitorTeamLocation+" "+mVisitorTeamName;
    }


    public int getHomeScore() {
        return mHomeScore;
    }

    public void setHomeScore(int homeScore) {
        mHomeScore = homeScore;
    }

    public int getVisitorScore() {
        return mVisitorScore;
    }

    public void setVisitorScore(int visitorScore) {
        mVisitorScore = visitorScore;
    }


}

我的GameAdapter.java

    package com.brokenbroadcast.nba_project;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by steven on 1/16/2016.
 */
public class GameAdapter extends RecyclerView.Adapter<GameAdapter.GameViewHolder> {

    private List<Game> mGameList = new ArrayList<Game>();

    public GameAdapter(List<Game> gameList){
        mGameList=gameList;
    }

    @Override
    public GameViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view, parent, false);
        return new GameViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(GameViewHolder holder, int position) {
        Game curGame = mGameList.get(position);

        holder.vHomeScore.setText(curGame.getHomeScore()+"");
        holder.vVisitorScore.setText(curGame.getVisitorScore()+"");
        holder.vTitle.setText(curGame.getTitle());
        holder.vVisitorTeam.setText(curGame.getVisitorTeam());
    }

    @Override
    public int getItemCount() {
        return mGameList.size();
    }

    public class GameViewHolder extends RecyclerView.ViewHolder {
        private TextView vHomeTeam;
        private TextView vVisitorTeam;
        private TextView vTitle;
        private TextView vHomeScore;
        private TextView vVisitorScore;


        public GameViewHolder(View v) {
            super(v);
            vHomeTeam = (TextView) v.findViewById(R.id.homeTeam);
            vVisitorTeam = (TextView) v.findViewById(R.id.visitorTeam);
            vHomeScore = (TextView) v.findViewById(R.id.homeScore);
            vVisitorScore = (TextView) v.findViewById(R.id.visitorScore);
            vTitle = (TextView) v.findViewById(R.id.gameTitle);
        }
    }
}

如果有人能帮助我,我会非常感激。

2 个答案:

答案 0 :(得分:0)

在以下行中,您尝试访问从未初始化的列表。

GameAdapter ca = new GameAdapter(mNBA.getGameList());

确保mNBA不为空。您只声明变量但从未为其分配任何值。

同时声明:

private NBA mNBA = new NBA();

答案 1 :(得分:0)

分配mNBA = parseNBADetails(jsonData);看起来不会发生在与GameAdapter ca = new GameAdapter(mNBA.getGameList());相同的线程上,因此当调用后一个语句时,mNBA可能仍为空。

一种可能的解决方案是将该语句放在初始化mNBA

的同一个线程中
        public void onResponse(Response response) throws IOException {
            try {
                String jsonData = response.body().string();
                if (response.isSuccessful()) {
                    mNBA = parseNBADetails(jsonData);
                    GameAdapter ca = new GameAdapter(mNBA.getGameList()); // moved from onCreate
                    recList.setAdapter(ca); // moved from onCreate
                } else {
                    alertUserAboutError();
                }
            } catch (IOException e) {
            } catch (JSONException j) {
            }
        }