1
votes

Problèmes avec l'analyse JSON

Je travaille sur une application d'actualités simple. J'ai besoin de récupérer les données d'un serveur distant au format JSON, puis de les mettre en vue. J'utilise TabLayout et recyclerView pour afficher les catégories de données et Volley pour la requête sans API ici.

Le TabLayout est défini automatiquement en fonction des données de JSON où j'extrait le titre des onglets et le contenu de chaque onglet est affiché sur recyclerView (Titre de l'article , image, contenu, liens ...) et rendu à l'intérieur d'un fragment

J'ai passé plusieurs heures à essayer de le déboguer sans succès., mais quoi que je fasse, aucune donnée n'est affichée. Je ne sais pas ce que je fais de mal.

Je sais que ce n'est pas le bon endroit pour demander de telles choses, mais je suis un peu désespéré et j'aurais besoin d'un développeur expérimenté. problème.

Comment ça marche:

Activity lance BaseArticleFragment qui appelle une méthode qui charge les catégories de contenu et lie les données aux vues:

 public static ArrayList<Category> parseCategories(JSONObject jsonObject) {
    ArrayList<Category> categoryArrayList = new ArrayList<>();
    try {
        JSONArray categories = jsonObject.getJSONArray("categories");
        Category all = new Category();
        all.setTid("0");
        all.setName(ApplicationController.getInstance().getString(R.string.tab_all));
        categoryArrayList.add(all);
        for (int i = 0; i < categories.length(); i++) {
            JSONObject catObject = categories.getJSONObject(i);
            Category category = new Category();
            category.setTid(catObject.getString("tid"));
            category.setName(catObject.getString("name"));              
            categoryArrayList.add(category);
        }
        return categoryArrayList;

    } catch (JSONException e) {
        e.printStackTrace();
        return null;
    }

}


8 commentaires

Avez-vous vérifié que vous obtenez une réponse positive et non une erreur?


Il n'y a pas de code d'erreur dans le journal, mais le snack-bar de onErrorResponse (VolleyError vError) s'est déclenché


Dans ce cas, vérifiez "volleyError" pour voir quel code d'erreur est renvoyé


Aucun code d'erreur repéré là-bas


C'est étrange. S'il entre le code de réponse d'erreur, il doit y avoir quelque chose dans vError qui indique ce que c'est. Essayez de chercher ici: stackoverflow.com/questions/24700582/handle-volley-error et ici: stackoverflow.com/questions/21867929/... pour des exemples sur la façon d'identifier exactement de quel type d'erreur il s'agit.


Ou devrais-je l'imprimer sur stacktrace?


Aussi une bonne idée. Et ajoutez-le en tant que modification à la question.


J'ai suivi la recommandation de la question suggérée et j'obtiens une erreur de délai d'expiration


5 Réponses :


0
votes

Vérifiez simplement si vous avez défini LayoutManager pour recyclerView

recyclerView.setLayoutManager(new LinearLayoutManager(MyActivity.this));


0 commentaires

0
votes

Pouvons-nous également avoir votre code et vos données JSON? Puisque nous ne pouvons pas lire ce que vous pensez ou sur votre ordinateur ... Veuillez apporter quelques modifications à votre message, ajouter du code et des données JSON afin que nous puissions vous aider.


0 commentaires

1
votes

Vous avez oublié d'ajouter cette chose à la fin de la méthode "load":

Volley.newRequestQueue (this) .add (jsonRequest);

Essayez de ajoutez-le ...

Au lieu d'utiliser new RequestQueue , veuillez utiliser RequestQueue jsonQueue = new RequestQueue

Comme ceci:

    RequestQueue requestQueue = Volley.newRequestQueue(this);
        String url = "https://someurl.com/api";
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {

JSONArray ja = new JSONArray(response);

for(int i = 0; i < ja.length(); i++)
{
       JSONObject jo = ja.get(i);

       String name = jo.getString("name");
}

        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("LOG", error.toString());
            }
        });
        requestQueue.add(jsonObjectRequest);


15 commentaires

Quelque chose ne fonctionne pas, je ne peux obtenir l'erreur que du snack-bar,


@esQmo_ Erreur sur le Snackbar? Je vois que vous travaillez dans le fragment, en fragment, au lieu de activity.this, veuillez utiliser getActivity ()


Oui je l'ai modifié, bien que l'EDI avertisse qu'il pourrait être nul


Mais c'est essentiellement ce que je fais, j'ai une classe ApplicationController


Non j'ai un écran blanc et toujours le message du snack, donc erreur de Volley je suppose?


Ohh, c'est un snack-bar, il a besoin de 'View', pas de contexte comme premier paramètre, veuillez utiliser findViewById (R.id.yourLayoutId); et essayez à nouveau


Oh, le snack-bar que j'utilise pour afficher un message lorsque quelque chose ne va pas, aucun article ne peut être chargé et il s'affiche bien avec ce message


@esQmo_ Je pense que quelque chose ne va pas dans la méthode onResponse. essayez d'utiliser JSONArray ja = response.getJsonArray ();


Que doit-il faire?


Convertit votre JSON d'url en JSONArray


Le problème peut être que je suis confronté à une erreur TimeOut


@esQmo_ J'ai à nouveau édité mon code, ce code obtient l'objet JSON (par exemple, nom, je veux dire sujet 1) en chaîne, vous pouvez alors utiliser cette chaîne quand et où vous voulez ...


En passant, une telle demande fonctionne. Mais j'ajoute la réponse aux catégories, qui est un objet BaseAarticleFragment (protected static ArrayList categories = null;)


@esQmo_ Vous l'ajoutez donc à votre arraylist personnalisé, dites-vous?


Oui, pourriez-vous regarder tout mon projet? Pour mieux comprendre



2
votes

Essayez ceci @esQmo_,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/name"
    />

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tid"
    />


</LinearLayout>

Voici la classe d'adaptateur

public class ExampleAdpater extends RecyclerView.Adapter<ExampleAdpater.ExampleViewHolder>{

public ArrayList<HashMap<String,String>> arraylist;

public Context context;

public ExampleAdpater(ArrayList<HashMap<String, String>> arraylist, Context context) {
    this.arraylist= arraylist;
    this.context = context;
}

@NonNull
@Override
public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.textLayout,viewGroup,false);
    return new ExampleViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ExampleViewHolder viewHolder, int i) {

    HashMap<String,String> hashMap = arraylist.get(i);
    viewHolder.name.setText(hashMap.get("name"));
    viewHolder.tid.setText(hashMap.get("tid"));

}

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

public class ExampleViewHolder extends RecyclerView.ViewHolder{

    TextView name,tid;

    public ExampleViewHolder(@NonNull View itemView) {
        super(itemView);

        name = itemView.findViewById(R.id.name);
        tid = itemView.findViewById(R.id.tid);

        name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(v.getContext(), ""+name.getText().toString(), 
          Toast.LENGTH_SHORT).show();
            }
        });

        }
   }
  }

textLayout.xml

StringRequest stringRequest = new StringRequest(url , new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                try {
                    JSONArray jsonArray = new JSONArray(response);

                    ArrayList<Hashmap<String,String>> arraylist = new 
                                                            ArrayList<>();
                    for (int i = 0; i < jsonArray.length(); i++) {

                    HashMap<String, String> hashMap = new HashMap<>();
               String name = 
                      jsonArray.getJSONObject(i).getString("name");
                     String tid = 
                     jsonArray.getJSONObject(i).getString("tid");

                     hashMap.put("name", name);
                     hashMap.put("tid ", tid ); 
                     arraylist.add(hashMap);
                     Log.e("response",name + "\n" + tid);
                   }

              attachAdapter(arraylist);

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

        RequestQueue queue = Volley.newRequestQueue(this);
        queue.add(stringRequest);

     //setting adapter data to the RecyclerView
    private void attachAdapter(ArrayList<HashMap<String, String>> 
    arrayList) {

    ExampleAdapter adapter = new ExampleAdapter(arrayList,this);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(adapter);
    adapter.notifyDataSetChanged();
 }
}


9 commentaires

Cela fonctionne, mais rappelez-vous: j'ajoute la réponse aux catégories qui est un objet BaseArticleFragment (protégé statique ArrayList categories = null;) puis définissez mon adaptateur


Comme j'ai essayé de l'expliquer dans ma question, aucune donnée n'est affichée sur les vues. L'activité est vide et j'obtiens une erreur de volley expirée


Avez-vous vérifié en mettant toute ma réponse? Je veux dire que ça marche bien pour moi quand j'utilise la volée de cette façon


Mon approche est assez différente. J'ai la même chose sur ma méthode parseCategories ()


D'accord, je vais vérifier @esQmo_


nous pouvons le faire facilement en utilisant Hashmap @esQmo_. Je peux modifier la réponse pour vous en utilisant le concept HashMap.


J'utilise un ensemble quelque part. Voulez-vous examiner l'ensemble du projet?


Bien sûr @esQmo_ je vais examiner cela


continuons cette discussion dans le chat



0
votes

Comme vous obtenez une erreur de délai d'expiration, vous pouvez modifier la valeur du délai d'expiration afin qu'il soit prêt à attendre plus longtemps.

Essayez quelque chose comme ceci:

requestQueue.add(jsonObjectRequest);

où MY_SOCKET_TIMEOUT_MS est la durée (en millisecondes) que vous souhaitez attendre avant un délai d'expiration. Commencez par 5000 (5 secondes) et jouez avec.

Faites-le avant

jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
MY_SOCKET_TIMEOUT_MS, 
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));


2 commentaires

J'ai essayé d'ajouter les lignes et de jouer avec la valeur, cela n'a pas fonctionné. Le message d'erreur apparaît dès le lancement de l'activité


Vous pouvez essayer de le déplacer vers onAttach car cela se produit plus tôt, mais vous ne savez pas si cela aidera