使用Retrofit2在响应主体上获取空数据?

时间:2019-05-27 07:19:20

标签: java android gson retrofit2 response

我是改造2的新手,我试图获取json数组数据,但获取null,这是获取数据的网址。

但是有趣的是,当我尝试在onResponse内进行调试时,我收到了成功消息以及response.body数据。这是什么问题?

https://xenzet.com/GameCheat/viewgamesjson.php

这是json数据

[
    {
        "gameid":"2",
        "gameIcon":"https:\/\/xenzet.com\/GameCheat\/uploads\/counter strike 1.6.png",
        "Games_Name":"1"
    },
    {
        "gameid":"3",
        "gameIcon":"https:\/\/xenzet.com\/GameCheat\/uploads\/gta.ico",
        "Games_Name":"vice city sucjlfsdrgefdsrhag"
    },
    {
        "gameid":"4",
        "gameIcon":"https:\/\/xenzet.com\/GameCheat\/uploads\/pubg.png",
        "Games_Name":"pubg"
    },
    {
    "gameid":"5",
    "gameIcon":"https:\/\/xenzet.com\/GameCheat\/uploads\/doom.png",
    "Games_Name":"Doom Enternal"
    },
    {
    "gameid":"6",
    "gameIcon":"https:\/\/xenzet.com\/GameCheat\/uploads\/for.png",
    "Games_Name":"Fornite"
    },
    {
    "gameid":"9",
    "gameIcon":"https:\/\/xenzet.com\/GameCheat\/uploads\/dota2.png",
    "Games_Name":"dota2"
    }
]

这是试图获取数据的方法

 public void fetch_information() {

        ApiInterface = ApiClient.getApiClient().create(Api.class);

        Call<List<Games>> call = ApiInterface.GetGames();


        call.enqueue(new Callback<List<Games>>() {
            @Override
            public void onResponse(Call<List<Games>> call, Response<List<Games>> response) {
                if(response.isSuccessful()) {

                    gameslist = response.body();
                    gamescounter = gameslist.size();
                    adapter = new GameRecyclerViewAdapter(GamesActivity.this, gameslist);
                    recyclerView.setAdapter(adapter);
                }
            }


            @Override
            public void onFailure(Call<List<Games>> call, Throwable t) {
                Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });

    }

这是ApiClient

public class ApiClient {

    public static  String Base_URL ;

    public static Retrofit retrofit;

    public static Retrofit getApiClient()
    {
        if (retrofit == null)
        {
            Base_URL ="https://xenzet.com/GameCheat/";
            retrofit = new Retrofit.Builder().baseUrl(Base_URL)
                    .addConverterFactory(GsonConverterFactory.create()).build();

        }
        return retrofit;
    }
}

和Api

public interface Api {

    @GET("viewgamesjson.php")
    Call<List<Games>> GetGames();
}

在OnCreate中,我正在调用获取信息方法。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_games);
    gameslist = new ArrayList<Games>();
    RecyclerView recyclerView = findViewById(R.id.recyclerview_gameslist);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
     fetch_information();

    Toast.makeText(getApplicationContext(),"" +gamescounter, Toast.LENGTH_SHORT).show();

    adapter = new GameRecyclerViewAdapter(this, gameslist);

   recyclerView.setAdapter(adapter);
    adapter.setClickListener((GameRecyclerViewAdapter.ItemClickListener) this);
}

试图在回收站视图中填充游戏列表数据,但由于它为空而失败。

这是logcat

2019-05-27 14:03:43.261 1261-1261/com.example.quizgames E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.quizgames, PID: 1261
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)' on a null object reference
    at com.example.quizgames.GamesActivity$1.onResponse(GamesActivity.java:109)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
    at android.os.Handler.handleCallback(Handler.java:836)
    at android.os.Handler.dispatchMessage(Handler.java:103)
    at android.os.Looper.loop(Looper.java:203)
    at android.app.ActivityThread.main(ActivityThread.java:6251)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)

这是类游戏

public class Games {

    @SerializedName("gameid")
    @Expose
    private String gameid;
    @SerializedName("gameIcon")
    @Expose
    private String gameIcon;
    @SerializedName("Games_Name")
    @Expose
    private String gamesName;

    public String getGameid() {
        return gameid;
    }

    public void setGameid(String gameid) {
        this.gameid = gameid;
    }

    public String getGameIcon() {
        return gameIcon;
    }

    public void setGameIcon(String gameIcon) {
        this.gameIcon = gameIcon;
    }

    public String getGamesName() {
        return gamesName;
    }

    public void setGamesName(String gamesName) {
        this.gamesName = gamesName;
    }

//    public Games(String Gameid,String Gameicon,String GameName)
//    {
//      this.gameid = Gameid;
//      this.gameIcon = Gameicon;
//      this.gamesName = GameName;
//
//    }

}

这是回收站视图

class GameRecyclerViewAdapter extends RecyclerView.Adapter<GameRecyclerViewAdapter.ViewHolder> {

    private List<Games> mGames;
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;

    // data is passed into the constructor
    GameRecyclerViewAdapter(Context context, List<Games> games) {
        this.mInflater = LayoutInflater.from(context);
        this.mGames = games;
    }

    // inflates the row layout from xml when needed
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.gameitem, parent, false);
        return new ViewHolder(view);
    }



    // binds the data to the TextView in each row
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Games Game = mGames.get(position);
        String Gameid = Game.getGameid();
        String Gameicon = Game.getGameIcon();
        String Gamename = Game.getGamesName();
        holder.GameNameTxt.setText(Gamename);
        Glide.with(holder.GameIconImage.getContext()).load(Game.getGameIcon()).thumbnail(0.1f).
                placeholder(R.color.colorPrimary).diskCacheStrategy(DiskCacheStrategy.NONE).into(holder.GameIconImage);

    }

    // total number of rows
    @Override
    public int getItemCount() {


        return mGames == null ? 0 : mGames.size();

    }


    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView GameNameTxt;
        ImageView GameIconImage;
        ViewHolder(View itemView) {
            super(itemView);
            GameNameTxt = itemView.findViewById(R.id.gamename);
            GameIconImage = itemView.findViewById(R.id.imageView);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }


    // allows clicks events to be caught
    void setClickListener(ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }

    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);

    }
}

3 个答案:

答案 0 :(得分:0)

在侧面的onResponse方法中向适配器添加数据

在oncreate中添加fetch_information()

@Override
        public void onResponse(Call<List<Games>> call, Response<List<Games>> response) {
            if(response.isSuccessful()) {
                gameslist = response.body();
                adapter = new GameRecyclerViewAdapter(MainActivity.this, gameslist); 
                //change your Activity name here insted of MainActivity
                recyclerView.setAdapter(adapter);
            }
        }

答案 1 :(得分:0)

问题是,您在on gameslist仍然为null的onCreate()中设置了列表适配器。

adapter = new GameRecyclerViewAdapter(this, gameslist);
recyclerView.setAdapter(adapter);

当您调用setAdapter()方法时,recyclerView将询问适配器其项目数;我想在getItemCount()中,您有类似return gameslist.count()的内容。由于游戏列表仍然为空,因此会导致NPE。

要修复此问题,请将getItemCount()更改为以下内容:

return gameslist == null ? 0 : gameslist.size()

编辑

我(用邮递员)检查了您的URL,看来响应的内容类型是text/html,而不是应该的application/json。我想因此响应不会使用Gson转换,因此您最终会得到null。

答案 2 :(得分:0)

我没有检查您在哪里犯错。但是此代码实现返回了我在列表中具有10个数据的列表。

public interface APIInterface {

    @GET()
    Call<List<ViewGame>> viewgamesjson(@Url String url);

}

这是模型类:

public class ViewGame {
    String gameid,gameIcon,Games_Name;

    public String getGameid() {
        return gameid;
    }

    public void setGameid(String gameid) {
        this.gameid = gameid;
    }

    public String getGameIcon() {
        return gameIcon;
    }

    public void setGameIcon(String gameIcon) {
        this.gameIcon = gameIcon;
    }

    public String getGames_Name() {
        return Games_Name;
    }

    public void setGames_Name(String games_Name) {
        Games_Name = games_Name;
    }
}

这是APiClient类:

public class APIClient {
    static Retrofit retrofit = null;

    public static String Base_URL = "https://xenzet.com/GameCheat/";


    public static APIInterface getInterface() {

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(interceptor)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(Base_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        return retrofit.create(APIInterface.class);
    }
}

这是API调用:

 private void viewGame() {
        Call<List<ViewGame>> call = APIClient.getInterface().viewgamesjson("https://xenzet.com/GameCheat/viewgamesjson.php");

        call.enqueue(new Callback<List<ViewGame>>() {
            @Override
            public void onResponse(Call<List<ViewGame>> call, Response<List<ViewGame>> response) {
                try {
                    Global.dismissProgress();

                    if (response.isSuccessful() && response.body() != null) {
                        Global.dismissProgress();

                        Global.printLog("size===", response.body().size() + "");

                    } else {
                        Global.dismissProgress();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Global.dismissProgress();
                }
            }

            @Override
            public void onFailure(Call<List<ViewGame>> call, Throwable t) {
                Global.dismissProgress();
                try {
                    Global.showToast(SplashActivity.this, getString(R.string.something_wrong));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                call.cancel();
                t.printStackTrace();
            }
        });
    }