Reputation: 11
Good evening, I'm currently on a project using the PokeApi API at "https://pokeapi.co/api/v2/". I want to do different JSON reads to retrieve varied information about first generation pokemons. I come to my problem. When I read in the JSON using a BufferedInputStream, on the second successive read an error occurs. This happens when I click on a pokemon in my listView, this ui is supposed to display details about the pokemon. This is a global exception and I can't get more information on it. It occurs in my 'HttpHandler.java' class, l.37. I have no idea, I checked: I closed connections after opening and tried to use 'AsyncTask' to manage connections.
Here are some classes: ListeActivity.java which allows me to display the list of pokemons, RecuperationPokemonJSONListe.java which allows me to retrieve the info I want to display the pokemons in the listeView, RecuperationPokemonJSONListe.java allowing me to retrieve info from a particular pokemon.
I also take this opportunity to put the classes ListeActivity.java and PokemonDetailActivity.java as well as the errors that I encounter.
Anyway, thank you for any insights you can give me.
public class ListeActivity extends AppCompatActivity {
private ListView listePokemons;
private ArrayList<Pokemon> listePokemon;
private ProgressDialog progressDialog;
private SearchView mySearchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_liste);
mySearchView = (SearchView)findViewById(R.id.searchView);
//on définit le texte par defaut de notre barre de recherche
mySearchView.setQueryHint("Ecrivez un nom de pokemon");
listePokemons = (ListView) findViewById(R.id.liste_pokemons);
executeInThread();
}
private void executeInThread(){
onPreExecute();
RecuperationPokemonJSONListe<Pokemon> getPokemon = new RecuperationPokemonJSONListe();
Runnable runnable = ()->{
getPokemon.doInBackground();
runOnUiThread( ()-> onPostExecute( getPokemon.getItemResult()) );
};
Executors.newSingleThreadExecutor().execute( runnable );
}
/**
* This method is called before the asynchronous webConnexion start
*/
private void onPreExecute() {
progressDialog = new ProgressDialog(ListeActivity.this);
progressDialog.setMessage("Accès aux données des pokémons...");
progressDialog.setCancelable(false);
progressDialog.show();
}
private void onPostExecute(ArrayList<Pokemon> pokemonList) {
progressDialog.dismiss();
//on associe la liste de pokemon à la liste de pokemon de la classe
this.listePokemon = pokemonList;
// référence pour l'adaptateur de liste complète de Pokemon
PokemonAdapter fullAdapter = new PokemonAdapter(getApplicationContext(), pokemonList);
// référence pour l'adaptateur de liste filtrée
PokemonAdapter filteredAdapter = new PokemonAdapter(getApplicationContext(), pokemonList);
// Utilisez l'adaptateur de liste complète de Pokemon pour afficher la liste au départ
listePokemons.setAdapter(fullAdapter);
// Lorsque l'utilisateur modifie le texte dans la barre de recherche
mySearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
@Override
public boolean onQueryTextSubmit(String s){
return false;
}
@Override
public boolean onQueryTextChange(String s){
if (TextUtils.isEmpty(s)) {
// Si la barre de recherche est vide, adaptateur de liste complète de Pokemon pour réinitialiser la liste
listePokemons.setAdapter(fullAdapter);
}
else {
// Sinon, adaptateur filtré pour afficher les éléments filtrés
filteredAdapter.getFilter().filter(s);
listePokemons.setAdapter(filteredAdapter);
}
return true;
}
});
listePokemons.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent pokemonDetailActivity = new Intent(ListeActivity.this, PokemonDetailActivity.class);
int idPok = listePokemon.get(position).getId();
pokemonDetailActivity.putExtra("POKEMON_SELECTION_ID", idPok);
startActivity(pokemonDetailActivity);
}
});
}
}
public class PokemonDetailActivity extends AppCompatActivity {
private int idPokemon;
private RecuperationDetailPokemonJSON detailsPokemon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pokemon_detail);
idPokemon = getIntent().getIntExtra("POKEMON_SELECTION_ID", -1);
// on associe l'image du pokemon à l'imageView
ImageView imagePokemon = findViewById(R.id.imageview_pokemon);
imagePokemon.setImageBitmap(detailsPokemon.getImagePokemon());
// on associe le nom du pokemon au textView
TextView namePokemon = findViewById(R.id.nom_pokmeon);
namePokemon.setText(getApplicationContext().getString(R.string.nom) + detailsPokemon.getNamePokemon());
//on associe la postion du pokemon au textView
TextView positionPokemon = findViewById(R.id.posture_pokemon);
positionPokemon.setText(getApplicationContext().getString(R.string.posture) + detailsPokemon.getPosturePokemon());
// on associe la taille du pokemon au textView
TextView taillePokemon = findViewById(R.id.taille_pokemon);
taillePokemon.setText(getApplicationContext().getString(R.string.taille) + detailsPokemon.getTaillePokemon());
// on associe l'habitat du pokemon au textView
TextView habitatPokemon = findViewById(R.id.habitat_pokemon);
habitatPokemon.setText(getApplicationContext().getString(R.string.habitat) + detailsPokemon.getHabitatPokemon());
// on associe les stats du pokemon aux textView
TextView hpPokemon = findViewById(R.id.hp);
TextView attaquePokemon = findViewById(R.id.attaque);
TextView defensePokemon = findViewById(R.id.defense);
TextView attaqueSpePokemon = findViewById(R.id.attaque_speciale);
TextView defenseSpePokemon = findViewById(R.id.defense_speciale);
TextView vitessePokemon = findViewById(R.id.vitesse);
hpPokemon.setText(getApplicationContext().getString(R.string.hp) + detailsPokemon.getStatsPokemon().get(0).toString());
attaquePokemon.setText(getApplicationContext().getString(R.string.attaque) + detailsPokemon.getStatsPokemon().get(1).toString());
defensePokemon.setText(getApplicationContext().getString(R.string.defense) + detailsPokemon.getStatsPokemon().get(2).toString());
attaqueSpePokemon.setText(getApplicationContext().getString(R.string.attaqueSpe) + detailsPokemon.getStatsPokemon().get(3).toString());
defenseSpePokemon.setText(getApplicationContext().getString(R.string.defenseSpe) + detailsPokemon.getStatsPokemon().get(4).toString());
vitessePokemon.setText(getApplicationContext().getString(R.string.vitesse) + detailsPokemon.getStatsPokemon().get(5).toString());
}
private void executeInThread(){
RecuperationDetailPokemonJSON detailsPokemon = new RecuperationDetailPokemonJSON(idPokemon);
Runnable runnable = ()->{
detailsPokemon.doInBackground();
};
Executors.newSingleThreadExecutor().execute( runnable );
}
}
public class HttpHandler {
private static final String TAG = "theo_jessica " + RecuperationPokemonJSONListe.class.getSimpleName(); //Pour affichage en cas d'erreur
public String makeServiceCall(String reqUrl) {
HttpURLConnection urlConnection = null;
String response = null;
try {
URL url = new URL(reqUrl);
urlConnection = (HttpURLConnection) url.openConnection();
if (!url.getHost().equals(urlConnection.getURL().getHost())) {
// we were redirected! Kick the user out to the browser to sign on?
Log.d("ZZZZZZZZZZZZZZZZZZZZZ", "on est redirigé");
}
//urlConnection.setRequestMethod("GET");
// lecture du fichier
urlConnection.setUseCaches(false);
//InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
InputStream inputStream;
if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
inputStream = urlConnection.getErrorStream();
} else {
inputStream = urlConnection.getInputStream();
}
response = convertStreamToString(inputStream);
}
catch (MalformedURLException e) {
Log.e(TAG, "MalformedURLException: " + e.getMessage());
} catch (ProtocolException e) {
Log.e(TAG, "ProtocolException: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
finally {
if(urlConnection != null)
urlConnection.disconnect();
}
return response;
}
//Conversion flux en String
private String convertStreamToString(InputStream inputStream) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append('\n');
Log.e(TAG,line);
}
}
catch (IOException e) { e.printStackTrace(); }
finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return stringBuilder.toString();
}
}
public class RecuperationPokemonJSONListe<T> extends AsyncTask<Void, Void, ArrayList<T>> {
private static final String TAG = "theo_jessica " + RecuperationPokemonJSONListe.class.getSimpleName();
private ArrayList<T> itemList;
private HttpHandler webService;
private String urlPokemons = "https://pokeapi.co/api/v2/generation/1/";
private String URLImages = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/";
public RecuperationPokemonJSONListe() {
webService = new HttpHandler();
this.itemList = new ArrayList<>();
}
@Override
protected ArrayList<T> doInBackground(Void... voids) {
HttpURLConnection connection = null;
String jsonStr = webService.makeServiceCall(urlPokemons);
Log.d(TAG, "URL_ADDR liste pok : " + urlPokemons);
Log.d(TAG, "Response from url liste pok : " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
JSONArray pokemonSpecies = jsonObj.getJSONArray("pokemon_species");
for (int i = 0; i < pokemonSpecies.length(); i++) {
JSONObject pokemon = pokemonSpecies.getJSONObject(i);
String namePokemon = pokemon.getString("name");
String urlPokemon = pokemon.getString("url");
String[] urlSplit = urlPokemon.split("/");
int idPokemon = Integer.parseInt(urlSplit[urlSplit.length - 1]);
String imagePokemon = URLImages + idPokemon + ".png";
URL imageUrl = new URL(imagePokemon);
connection = (HttpURLConnection) imageUrl.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Bitmap bitmapImagePokemon = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
itemList.add((T) new Pokemon(bitmapImagePokemon, namePokemon, idPokemon));
}
} catch (JSONException e) {
throw new RuntimeException(e);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (connection != null) {
Log.d("$$$$$$$$$$$$$$$$$$$$$$$$", "ON PASSE ET ON DECONNECTE");
connection.disconnect();
}
}
}
return itemList;
}
@Override
protected void onPostExecute(ArrayList<T> itemList) {
super.onPostExecute(itemList);
// Mettez à jour l'interface utilisateur ou appelez une méthode avec itemList
}
public ArrayList<T> getItemResult() {
return itemList;
}
}
public class RecuperationDetailPokemonJSON extends AsyncTask<Void, Void, Void> {
private static final String TAG = "theo_jessica " + RecuperationPokemonJSONListe.class.getSimpleName();
private String urlPokemonDetails1 = "https://pokeapi.co/api/v2/pokemon-species/";
private String urlPokemonDetails2 = "https://pokeapi.co/api/v2/pokemon/";
private int idPokemon;
private HttpHandler webService;
private String URLImages = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/";
private Bitmap imagePokemon;
private String namePokemon;
private String posturePokemon;
private int taillePokemon;
private String habitatPokemon;
private ArrayList<Integer> statsPokemon;
public RecuperationDetailPokemonJSON(int idPokemon) {
webService = new HttpHandler();
this.idPokemon = idPokemon;
this.urlPokemonDetails1 += idPokemon + "/";
this.urlPokemonDetails2 += idPokemon + "/";
statsPokemon = new ArrayList<>();
}
@Override
protected Void doInBackground(Void... voids) {
HttpURLConnection connection = null;
// get the jsonStr to parse
String jsonStr1 = webService.makeServiceCall(urlPokemonDetails1);
Log.d(TAG, "URL_ADDR detail pok : " + urlPokemonDetails1);
Log.d(TAG, "Response from url detail pok : " + jsonStr1);
//parse jsonStr
if (jsonStr1 != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr1);
//get the image of the pokemon
URL imageUrl = new URL(URLImages + idPokemon + ".png");
connection = (HttpURLConnection) imageUrl.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
Bitmap bitmapImagePokemon = BitmapFactory.decodeStream(inputStream);
//get the name of the pokemon
String namePokemon = jsonObj.getString("name");
// get the living area of the pokemon
JSONObject habitat = jsonObj.getJSONObject("habitat");
String habitatPokemon = habitat.getString("name");
// get the shape of the pokemon
JSONObject shape = jsonObj.getJSONObject("shape");
String shapePokemon = shape.getString("name");
this.imagePokemon = bitmapImagePokemon;
this.namePokemon = namePokemon;
this.habitatPokemon = habitatPokemon;
this.posturePokemon = shapePokemon;
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (JSONException e) {
throw new RuntimeException(e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
String jsonStr2 = webService.makeServiceCall(urlPokemonDetails2);
Log.d(TAG, "URL_ADDR detail pok2 : " + urlPokemonDetails2);
Log.d(TAG, "Response from url detail pok2 : " + jsonStr2);
//parse jsonStr
if (jsonStr2 != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr2);
// get the height of the pokemon
int heightPokemon = jsonObj.getInt("height");
// get the stats of the pokemon
JSONArray stats = jsonObj.getJSONArray("stats");
JSONObject stat = stats.getJSONObject(0);
JSONObject stat1 = stats.getJSONObject(1);
JSONObject stat2 = stats.getJSONObject(2);
JSONObject stat3 = stats.getJSONObject(3);
JSONObject stat4 = stats.getJSONObject(4);
JSONObject stat5 = stats.getJSONObject(5);
int hp = stat.getInt("base_stat");
int attack = stat1.getInt("base_stat");
int defense = stat2.getInt("base_stat");
int specialAttack = stat3.getInt("base_stat");
int specialDefense = stat4.getInt("base_stat");
int speed = stat5.getInt("base_stat");
this.taillePokemon = heightPokemon;
this.statsPokemon.add(hp);
this.statsPokemon.add(attack);
this.statsPokemon.add(defense);
this.statsPokemon.add(specialAttack);
this.statsPokemon.add(specialDefense);
this.statsPokemon.add(speed);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// Mettez à jour l'interface utilisateur ou appelez une méthode avec les résultats obtenus
}
public Bitmap getImagePokemon() {
return imagePokemon;
}
public String getNamePokemon() {
return namePokemon;
}
public String getPosturePokemon() {
return posturePokemon;
}
public int getTaillePokemon() {
return taillePokemon;
}
public String getHabitatPokemon() {
return habitatPokemon;
}
public ArrayList<Integer> getStatsPokemon() {
return statsPokemon;
}
}
The errors :
I tried to extends AsyncTask<> but that didn't worked and take care to close all the connections open with urls. I have no other idea.
Upvotes: 1
Views: 136