Получение нулевых данных о теле ответа с использованием retrofit2? - PullRequest
1 голос
/ 27 мая 2019

Я новичок в модификации 2, и я пытаюсь получить данные массива json, но получаю ноль, это URL для получения данных.

Но самое смешное, когда я пытаюсь отладить внутри 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 голосов
/ 27 мая 2019

Проблема в том, что вы настроили свой адаптер списка в onCreate (), где gameslist по-прежнему равно нулю.

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

Когда вы вызываете метод setAdapter (), recyclerView запросит у адаптера количество элементов;и в getItemCount (), я полагаю, у вас есть что-то вроде return gameslist.count ().Так как список игр по-прежнему равен нулю, это приводит к тому, что NPE.

Чтобы исправить это, измените getItemCount () на что-то вроде этого:

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

EDIT

Я проверил ваш URL (с почтальоном), и похоже, что тип содержимого ответа text/html, а не application/json, как и должно быть.Я полагаю, что поэтому ответ не конвертируется с помощью Gson, и в результате вы получаете нулевое значение.

0 голосов
/ 27 мая 2019

Я не проверял, где ты ошибаешься. Но эта реализация кода возвращает мне список с 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 Call:

 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();
            }
        });
    }
0 голосов
/ 27 мая 2019

Добавьте данные в свой адаптер в методе onResponse

добавить 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);
            }
        }
...