如何发送多个Json请求并使用数据

时间:2016-05-22 21:15:37

标签: android json wordpress android-recyclerview

我正在练习为wordpress博客构建一个Android应用程序,我基本上想要做的是fetech帖子标题和它的作者。我能够毫无困难地获得并显示帖子标题,但是令人头疼的是帖子的作者。

这是json https://hmn.md/wp-json/wp/v2/posts

的链接

这是我的代码

PostItems

public class PostItems implements Parcelable {
    private String post_title;
    private String post_author;

    public String getPost_title() {
        return post_title;
    }

    public void setPost_title(String post_title) {
        this.post_title = post_title;
    }



    public String getPost_author() {
        return post_author;
    }

    public void setPost_author(String post_author) {
        this.post_author = post_author;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.post_title);
        dest.writeString(this.post_author);
    }

    public PostItems() {
    }

    protected PostItems(Parcel in) {
        this.post_title = in.readString();
        this.post_author = in.readString();
    }

    public static final Parcelable.Creator<PostItems> CREATOR = new Parcelable.Creator<PostItems>() {
        @Override
        public PostItems createFromParcel(Parcel source) {
            return new PostItems(source);
        }

        @Override
        public PostItems[] newArray(int size) {
            return new PostItems[size];
        }
    };
}

PostList的一部分

...
private void getData(){
         Log.d(TAG, "getData called");
         final ProDialoFrag dialoFrag = ProDialoFrag.newInstance();
         dialoFrag.show(getFragmentManager(), "fragmentDialog");


         //Creating a json request
         jsonArrayRequest = new JsonArrayRequest(GET_URL,
                 new Response.Listener<JSONArray>() {
                     @Override
                     public void onResponse(JSONArray response) {
                         Log.d(TAG, "onResponse called");
                         //Dismissing the progress dialog
                         if (dialoFrag != null ) {
                             dialoFrag.dismiss();
                         }
                         //calling method to parse json array
                         parseData(response);

                     }
                 },
                 new Response.ErrorListener() {
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         if (dialoFrag != null) {
                             dialoFrag.dismiss();
                         }
                         if (sthWrongAlert != null) {
                             sthWrongAlert.show();
                         }

                     }
                 }) {

         };

         //Creating request queue
         RequestQueue requestQueue = Volley.newRequestQueue(getActivity());

         //Adding request to the queue
         requestQueue.add(jsonArrayRequest);

     }

     //This method will parse json data
     private void parseData(JSONArray array){
         Log.d(TAG, "Parsing array");

         mPostItemsList.clear();


         for(int i = 0; i<array.length(); i++) {
             PostItems postItem = new PostItems();
             JSONObject jsonObject = null;
             try {
                 jsonObject = array.getJSONObject(i);

                 JSONObject postTitle = jsonObject.getJSONObject("title");
                 postItem.setPost_title(postTitle.getString("rendered"));

                 JSONObject links = jsonObject.getJSONObject("_links");
                 JSONArray authorLink = links.getJSONArray("author");
                 String authorhref = authorLink.getJSONObject(0).getString("name")



                 postItem.setPostId(jsonObject.getString("link"));
             } catch (JSONException w) {
                 w.printStackTrace();
                 //Toast.makeText(this, "Error in parsing Json", Toast.LENGTH_LONG).show();
             }

             mPostItemsList.add(postItem);

         }
         adapter.notifyItemRangeChanged(0, adapter.getItemCount());


     }

PostAdapter

      public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{


     private static Context mContext;


     //List of posts
     private List<PostItems> mPostItems;

     private final int VIEW_ITEM = 0;
     private final int VIEW_PROG = 1;

     private int lastPosition = -1;


    public PostAdapter(List<PostItems> postItems, Context context) {
        super();

        //Getting all posts
        this.mPostItems = postItems;
        this.mContext = context;
    }


     @Override
     public int getItemViewType(int position) {
         if (isPositionItem(position))
             return VIEW_ITEM;
         return VIEW_PROG;
     }

     private boolean isPositionItem(int position) {
        return position != getItemCount()-1;
     }



     @Override
     public RecyclerView.ViewHolder  onCreateViewHolder (ViewGroup parent, int viewType) {
         if (viewType == VIEW_ITEM) {
             View v =  LayoutInflater.from(parent.getContext())
                     .inflate(R.layout.post_summ, parent, false);
             return new CardDetails(v);
         } else if (viewType == VIEW_PROG){
             View v = LayoutInflater.from(parent.getContext())
                     .inflate(R.layout.recyclerfooter, parent, false);
             return new ProgressViewHolder(v);
         }

         return null;
     }



     @Override
     public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

         if (holder instanceof CardDetails) {
             final PostItems postList = mPostItems.get(position);

             ((CardDetails) holder).postTitle.setText(Html.fromHtml(postList.getPost_title()));
             ((CardDetails) holder).postAuthor.setText(postList.getPost_author());


         } else {
             ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
         }


     }

     @Override
     public int getItemCount(){
         //Return the number of items in the data set
         return mPostItems.size();
     }


     public class CardDetails extends RecyclerView.ViewHolder implements View.OnClickListener {
         public TextView postTitle, postAuthor;

         public CardDetails (final View postView) {
             super(postView);
             postTitle = (TextView) postView.findViewById(R.id.post_title);
             postAuthor = (TextView) postView.findViewById(R.id.post_author);
         }

     }

     public  class ProgressViewHolder extends RecyclerView.ViewHolder{
         ProgressBar progressBar;
         public ProgressViewHolder(View footerView){
             super(footerView);
             progressBar = (ProgressBar) footerView.findViewById(R.id.progress_load);
             progressBar.setVisibility(View.VISIBLE);
         }

     }


 }

我当前的解决方案

 private void parseData(JSONArray array){
         Log.d(TAG, "Parsing array");


         for(int i = 0; i<array.length(); i++) {
             JSONObject jsonObject;
             try {
                 jsonObject = array.getJSONObject(i);

                 JSONObject postTitle = jsonObject.getJSONObject("title");
                 String postT = postTitle.getString("rendered");
                 mPostTitle = postT;


                 JSONObject links = jsonObject.getJSONObject("_links");
                 JSONArray authorLink = links.getJSONArray("author");
                 authorhref = authorLink.getJSONObject(0).getString("href");


                 getAuthor();

             } catch (JSONException w) {
                 w.printStackTrace();
                 //Toast.makeText(this, "Error in parsing Json", Toast.LENGTH_LONG).show();
             }

         }


     }

     private void getAuthor() {
         Log.d(TAG, "getAuthor called");

         JsonObjectRequest authorRequest = new JsonObjectRequest(authorhref, null,
                 new Response.Listener<JSONObject>() {
                     @Override
                     public void onResponse(JSONObject response) {
                         Log.d(TAG, "onResponse called");
                         parseAuthor(response);
                     }
                 },
                 new Response.ErrorListener() {

                     @Override
                     public void onErrorResponse(VolleyError error) {

                     }
                 });

         authorRequest.setShouldCache(false);

         RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
         requestQueue.add(authorRequest);

     }

     private void parseAuthor (JSONObject object) {
         Log.d(TAG, "Parsing author");
         PostItems postItem = new PostItems();

         try {
             String authorname = object.getString("name");
             postItem.setPost_author(authorname);
             postItem.setPost_title(mPostTitle);
         } catch (JSONException w) {
             w.printStackTrace();
         }
         mPostItemsList.add(postItem);
         adapter.notifyItemRangeChanged(0, adapter.getItemCount());
     }

问题在于我的解决方案是所有帖子都是相同的。为了进一步解释,作者的名字是它们应该是什么,但所有的帖子标题都是最后一篇文章的标题。

请知道如何解决这个问题?

应用kris larson的答案后

PostFragment的一部分

public class PostFragment extends Fragment{

    private List<PostItems> mPostItemsList = new ArrayList<>();
    ...
    // Nothing changed here, just added it so you will understand my code better
    ObservableRecyclerView recyclerView;
        private RecyclerView.Adapter adapter;
        LinearLayoutManager mLayoutManager;


        public PostFragment() {
            // Required empty public constructor
        }


        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            String title = getArguments().getString("title");
            // Inflate the layout for this fragment
            view = inflater.inflate(R.layout.fragment_post, container, false);
            //Initializing Views
            recyclerView = (ObservableRecyclerView) view.findViewById(R.id.post_recycler);
            recyclerView.setScrollViewCallbacks(this);
            mLayoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager( mLayoutManager);
            ...

    //This method will get data from the web api
        private void getData(){
            Log.d(TAG, "getData called");
            final ProDialoFrag dialoFrag = ProDialoFrag.newInstance();
            dialoFrag.show(getFragmentManager(), "fragmentDialog");


            //Creating a json request
            jsonArrayRequest = new JsonArrayRequest(GET_URL,
                    new Response.Listener<JSONArray>() {
                        @Override
                        public void onResponse(JSONArray response) {
                            Log.d(TAG, "onResponse called");
                            //Dismissing the progress dialog
                            if (dialoFrag == null ) {
                                dialoFrag.dismiss();
                            }
                            //calling method to parse json array
                            parseData(response);

                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            if (dialoFrag != null) {
                                dialoFrag.dismiss();
                            }
                            if (sthWrongAlert != null) {
                                sthWrongAlert.show();
                            }

                        }
                    }) {
                n Response.success(resp.result, entry);
                }
            };

            //Creating request queue
            RequestQueue requestQueue = Volley.newRequestQueue(getActivity());

            //Adding request to the queue
            requestQueue.add(jsonArrayRequest);

        }

        //This method will parse json data
        private void parseData(JSONArray array){
            Log.d(TAG, "Parsing array");

            for(int i = 0; i<array.length(); i++) {

                JSONObject jsonObject;
                try {
                    jsonObject = array.getJSONObject(i);

                    JSONObject postTitle = jsonObject.getJSONObject("title");
                    String title = postTitle.getString("rendered"));

                    JSONObject links = jsonObject.getJSONObject("_links");
                    JSONArray authorLink = links.getJSONArray("author");
                    String authorhref = authorLink.getJSONObject(0).getString("href");

                    PostItems postItem = new PostItems();
                    postItem.setPost_title(title);
                    postItem.setPostAuthorUrl(authorhref);
                    mPostItemsList.add(postItem);

                    if (adapter.getAuthor(authorhref) == null) {
                        getAuthor(authorhref);
                    }
                } catch (JSONException w) {
                    w.printStackTrace();
                    //Toast.makeText(this, "Error in parsing Json", Toast.LENGTH_LONG).show();
                }



            }
            adapter.setPostItems(mPostItemsList);


        }

        private void getAuthor (String authorhref) {
            Log.d(TAG, "getAuthor called");

            JsonObjectRequest authorRequest = new JsonObjectRequest(authorhref, null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            Log.d(TAG, "onResponse called");
                            parseAuthor(response);
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            //Do nothing
                        }
                    });
            authorRequest.setShouldCache(false);
            RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
            requestQueue.add(authorRequest);
        }
        private void parseAuthor (JSONObject object) {
            Log.d(TAG, "Parsing auhor");
            try {
                JSONObject links = object.getJSONObject("_links");
                JSONArray self = links.getJSONArray("self");
                String href = self.getJSONObject(0).getString("href");

                String authorname = object.getString("name");
                adapter.putAuthor(href, authorname);
            } catch (JSONException w) {
                w.printStackTrace();
            }
        }

}

PostAdapter

public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{



    private ImageLoader imageLoader;
    private static Context mContext;


    //List of posts
    private List<PostItems> mPostItems;

    //authors by url
    private Map<String, String> mAuthorMap;

    //don't forget to initialoze in adapter constructor
    mAuthorMap = new HashMap<>();

    private final int VIEW_ITEM = 0;
    private final int VIEW_PROG = 1;

    private int lastPosition = -1;

    public void setPostItems(List<PostItems> postItems) {
        mPostItems = postItems;
        notifyDataSetChanged();
    }

    public void putAuthor(String url, String name) {
        mAuthorMap.put(url, name);
        notifyDataSetChanged();
    }

    public String getAuthor(String url) {
        return mAuthorMap.get(url);
    }


   public PostAdapter(List<PostItems> postItems, Context context) {
       super();

       //Getting all posts
       this.mPostItems = postItems;
       this.mContext = context;
   }


    @Override
    public int getItemViewType(int position) {
        if (isPositionItem(position))
            return VIEW_ITEM;
        return VIEW_PROG;
    }

    private boolean isPositionItem(int position) {
       return position != getItemCount()-1;
    }



    @Override
    public RecyclerView.ViewHolder  onCreateViewHolder (ViewGroup parent, int viewType) {
        if (viewType == VIEW_ITEM) {
            View v =  LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.post_summ, parent, false);
            return new CardDetails(v);
        } else if (viewType == VIEW_PROG){
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.recyclerfooter, parent, false);
            return new ProgressViewHolder(v);
        }

        return null;
    }



    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        if (holder instanceof CardDetails) {
            final PostItems postList = mPostItems.get(position);
            ((CardDetails) holder).postTitle.setText(Html.fromHtml(postList.getPost_title()));

            String name = mAuthorMap.get(postList.getPostAuthorUrl());
            if (name != null) {
                ((CardDetails) holder).postAuthor.setText(name);
            }

        } else {
            ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
        }


    }


    @Override
    public int getItemCount(){
        //Return the number of items in the data set
        return mPostItems.size();
    }





    public class CardDetails extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView postTitle, postAuthor;
        public ImageButton imageButton;

        public CardDetails (final View postView) {
            super(postView);
            postTitle = (TextView) postView

            .findViewById(R.id.post_title);
            postAuthor = (TextView) postView.findViewById(R.id.post_author);
        }


    }

    public  class ProgressViewHolder extends RecyclerView.ViewHolder{
        ProgressBar progressBar;
        public ProgressViewHolder(View footerView){
            super(footerView);
            progressBar = (ProgressBar) footerView.findViewById(R.id.progress_load);
            progressBar.setVisibility(View.VISIBLE);
        }

    }


}

我目前遇到的问题

  1. 在PostFragment中

    来自行if (adapter.getAuthor(authorhref) == null) { AS抱怨&#34;无法解析方法 getAuthor(Java.lang.String)

    从第adapter.setPostItems(mPostItemsList);无法解析meethod&#39; setPostItems(java.util.List.com.example.postapp.PostItems&gt;)&#39;

    从第adapter.putAuthor(href, authorname);无法解析方法&#39; putAuthor(java.lang.String)&#39;

  2. 在PostAdapter中

  3. 来自mAuthorMap = new HashMap<>(); &#39;未知类mAuthorMap&#39; 以及 Identifier expected 位置>

    方法setPostItemsputAuthorgetAuthor都说'方法从未使用过。

    parseAuthor方法中,我并没有真正理解你想要做什么,就好像你想要获得"self"数组一样;虽然我想要的是作者阵列。

1 个答案:

答案 0 :(得分:0)

如果您使用HttpURLConnectionAsyncTask,则可以在一次后台操作中同时发出这两个请求,并且没有任何问题。

但是因为看起来你致力于使用Volley,我建议你使用两阶段方法。在阶段1中,您解析帖子并保存帖子的作者URL。在阶段2中,您将作者姓名添加到由url索引的地图中。

  • PostItem包含作者网址而不是作者姓名:

    public class PostItem implements Parcelable {
        private String post_title;
        private String post_author_url;
        // also change all the getters/setters/parceling etc.
    }
    

    (我把它作为PostItem - 单数 - 因为它不是任何类型的同类集合。)

  • 在适配器中添加Map以包含作者姓名:

        /** posts, which contain author url */
        private List<PostItem> mPostItems;
    
        /** authors by url */
        private Map<String, String> mAuthorMap;
    
    不要忘记在适配器构造函数中初始化作者地图

    public PostAdapter(List<PostItems> postItems, Context context) {
        super();
    
        //Getting all posts
        this.mPostItems = postItems;
        this.mContext = context;
        this.mAuthorMap = new HashMap<>();
    }
    
  • 收到帖子时:

    1. 解析帖子项目
    2. 使用标题和作者网址
    3. 制作PostItem
    4. PostItem添加到适配器
    5. 向适配器询问作者
    6. 如果找不到作者,请启动新的作者请求

          private void parseData(JSONArray array){
      
              Log.d(TAG, "Parsing array");
      
              // Collect all the PostItems and add to adapter all at once
              List<PostItem> postItems = new ArrayList<>();
      
              for (int i = 0; i<array.length(); i++) {
                  JSONObject jsonObject;
                  try {
                      jsonObject = array.getJSONObject(i);
      
                      JSONObject postTitle = jsonObject.getJSONObject("title");
                      String title = postTitle.getString("rendered");
      
                      JSONObject links = jsonObject.getJSONObject("_links");
                      JSONArray authorLink = links.getJSONArray("author");
                      String authorhref = authorLink.getJSONObject(0).getString("href");
      
                      PostItem postItem = new PostItem();
                      postItem.setPostTitle(title);
                      postItem.setPostAuthorUrl(authorhref);
                      postItems.add(postItem);
      
                      if (mAdapter.getAuthor(authorhref) == null) {
                          getAuthor(authorhref);
                      }
      
                  } catch (JSONException w) {
                      w.printStackTrace();
                      //Toast.makeText(this, "Error in parsing Json", Toast.LENGTH_LONG).show();
                  }
              }
      
              mAdapter.setPostItems(postItems);
          }
      
  • 注意我更改了getAuthor方法以获取参数(而不是使用成员变量):

            private void getAuthor(String authorhref) {
                ...
    
  • 收到作者后,将其添加到适配器

            private void parseAuthor (JSONObject object) {
    
                Log.d(TAG, "Parsing author");
                try {
                    JSONObject links = jsonObject.getJSONObject("_links");
                    JSONArray self = links.getJSONArray("self");
                    String href = authorLink.getJSONObject(0).getString("href");
    
                    String authorname = object.getString("name");
                    mAdapter.putAuthor(href, name);
    
                } catch (JSONException w) {
                    w.printStackTrace();
                }
    
           }
    
  • 现在这里是新的适配器方法:

        public void setPostItems(List<PostItem> postItems) {
            mPostItems = postItems;
            notifyDataSetChanged();
        }
    
        public void putAuthor(String url, String name) {
            mAuthorMap.put(url, name);
            notifyDataSetChanged();
        }
    
        public String getAuthor(String url) {
            return mAuthorMap.get(url);
        }
    
  • onBindViewHolder就是它们聚集在一起的地方:

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    
            if (holder instanceof CardDetails) {
                final PostItem postItem = mPostItems.get(position);
                ((CardDetails) holder).postTitle.setText(Html.fromHtml(postItem.getPostTitle()));
    
                String name = mAuthorMap.get(postItem.getPostAuthorUrl());
    
                if (name != null) {
                    ((CardDetails) holder).postAuthor.setText(name);
                }
                // don't worry if author name is null, when it's retrieved
                // the adapter will be notified to refresh the list
    
            } else {
                ((ProgressViewHolder)  holder).progressBar.setIndeterminate(true);
            }
        }
    

编辑:获取作者网址的不同方式,而无需解析作者JSON - &gt; _links - &gt;自我[0] - &gt; HREF

        // notice that authorhref is final
        private void getAuthor (final String authorhref) {
            Log.d(TAG, "getAuthor called");

            JsonObjectRequest authorRequest = new JsonObjectRequest(authorhref, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d(TAG, "onResponse called");
                        parseAuthor(authorhref, response);  // pass authorhref with response
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        //Do nothing
                    }
                });
                authorRequest.setShouldCache(false);
                RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
                requestQueue.add(authorRequest);
            }

            private void parseAuthor (String authorhref, JSONObject object) {

                Log.d(TAG, "Parsing author");
                try {
                    String authorname = object.getString("name");
                    mAdapter.putAuthor(authorhref, name);

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

            }