0

Hi i am developing an app that would fetch JSON from this url

I am new to HttpConnection and parsing in Android.

Actually I am using seperate class called JSONParser.java to fetch JSON and return it as a String to another class called SecondFragment.java ( Trying to list out using recycler list view inside ViewPager )

I coundn't able to get the Json String from the URL. ie. Problem is in JSONParser, It is not fetching string from URL to return.

Below is code for JSONParser.java

public class JSONParser {

   // static InputStream is = null;
   // static JSONObject jObj = null;
    static String json = "";
String TAG="JSON Parser kbt";
    // constructor
    public JSONParser() {

    }

    public String getJSONFromUrl(String url) {

        // Making HTTP request
        try {
            Log.d(TAG,"STAET GETJSONFROMURL");
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            Log.d(TAG,"STAET AFTR HTTP POST");
            HttpResponse httpResponse = httpClient.execute(httpPost);
            Log.d(TAG,"STAET Aftr HTTP RESPONSE");
            HttpEntity httpEntity = httpResponse.getEntity();
            Log.d(TAG,"STAET AFTR HTTP ENTITY");
            is = httpEntity.getContent();
            Log.d(TAG,"END GETJSONFROMURL");
        } catch (UnsupportedEncodingException e) {Log.d(TAG,"Unsupported Encoding");
            e.printStackTrace();
        } catch (ClientProtocolException e) {Log.d(TAG,"ClientProtocolEx");
            e.printStackTrace();
        } catch (IOException e) {Log.d(TAG,"IOEX");
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }   

        // return JSON String
        Log.d(TAG,"RETURN JSON AS A STRING");
        return json;  // String is not returning

    }
}

After this line ,

HttpResponse httpResponse = httpClient.execute(httpPost);

Log.d is not printing.

I'll also post SecondFragment.java class also where i am calling the JSONParser class .

Calling JSONParser's method inside doInBackground().

public class SecondFragment extends Fragment {

    ArrayList<FeedItem> feedItemList;
    private static final String TAG = "SecondFragment kbt";
    private SimpleRecyclerAdapter adapter;
    RecyclerView recyclerView;String parsedJson;
     String urls = "https://api.myjson.com/bins/1vx7x";
    public SecondFragment() {

    }

   // @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "Start second fragment");

        View view = inflater.inflate(R.layout.secondfragment, container, false);

        recyclerView = (RecyclerView) view.findViewById(R.id.jsonrecyclerview);


        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setHasFixedSize(true);
        feedItemList = new ArrayList<>();

        new AsyncHttpTask().execute(urls);
        Log.d(TAG, "Last second fragment");

        return view;
    }



    public class AsyncHttpTask extends AsyncTask<String, String, Integer> {

        BufferedReader reader=null;

        @Override
        protected void onPreExecute() {
            //   setProgressBarIndeterminateVisibility(true);
            Log.d(TAG, "OnPreExecute");
        }

        @Override
        protected Integer doInBackground(String... params) {
Log.d(TAG,"DO IN BG START");
            Integer result = 0;
            JSONParser jobj=new JSONParser();
            parsedJson=jobj.getJSONFromUrl("http://api.myjson.com/bins/1vx7x");
            Log.d(TAG,"parsedJson string i s "+parsedJson);

             parseResult(parsedJson);
             result=1;            Log.d(TAG,"RETURN DO IN BG");
            return result;
        }

        @Override
        protected void onPostExecute(Integer result) {
            //setProgressBarIndeterminateVisibility(false);
            /* Download complete. Lets update UI */
         /* Download complete. Lets update UI */
            if (result == 1) {
                Log.i(TAG,"ON post exe");
                adapter = new SimpleRecyclerAdapter(getActivity(), feedItemList);
                recyclerView.setAdapter(adapter);
            } else {
                Log.e(TAG, "Failed to fetch data!");
            }


        }
        private void parseResult(String result) {
            try {
                JSONObject response = new JSONObject(result);
                JSONArray posts = response.optJSONArray("posts");

            /*Initialize array if null*/
                if (null == feedItemList) {
                    feedItemList = new ArrayList<FeedItem>();
                }

                for (int i = 0; i < posts.length(); i++) {
                    JSONObject post = posts.optJSONObject(i);

                    FeedItem item = new FeedItem();
                    item.setTitle(post.optString("title"));
                    item.setThumbnail(post.optString("thumbnail"));
                    feedItemList.add(item);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

    }



}

Thanks for your time to read my problem and thanks in advance for your valuable answers :)

Here is my SimpleRecyclerAdapter Class

public class SimpleRecyclerAdapter extends RecyclerView.Adapter<SimpleRecyclerAdapter.MainViewHolder> {
    List<String> versionModels;
    private ArrayList<FeedItem> feedItemList = new ArrayList<FeedItem>();
    private Context mContext;
    Boolean isHomeList = false;
    Boolean isJson=false;
    RecyclerView rv;
    private static final int TYPE_SIMPLELIST = 0;
    private static final int TYPE_JSONLIST = 1;

    public static List<String> homeActivitiesList = new ArrayList<String>();
    public static List<String> homeActivitiesSubList = new ArrayList<String>();
    Context context;
    OnItemClickListener clickListener;


    public void setHomeActivitiesList(Context context) {
        String[] listArray = context.getResources().getStringArray(R.array.home_activities);
        String[] subTitleArray = context.getResources().getStringArray(R.array.home_activities_subtitle);
        for (int i = 0; i < listArray.length; ++i) {
            homeActivitiesList.add(listArray[i]);
            homeActivitiesSubList.add(subTitleArray[i]);
        }
    }
    public SimpleRecyclerAdapter(Context context) {
        isHomeList = true;  Log.d("kbt","Constructor SIMPLE");
        this.context = context;
        setHomeActivitiesList(context);

    }
//   FOR JSON
    public SimpleRecyclerAdapter(Context context, ArrayList<FeedItem> feedItemList) {
        Log.d("kbt","Constructor JSON");
        isJson=true;
        this.feedItemList = feedItemList;
        this.mContext = context;
    }

    public SimpleRecyclerAdapter(List<String> versionModels) {
        isHomeList = false;
        this.versionModels = versionModels;

    }

    @Override
    public int getItemViewType(int position) {
        return position == 0 ? TYPE_SIMPLELIST : TYPE_JSONLIST;
    }

    @Override
    public MainViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        Log.d("kbt","Adapter Start OnCreate");
        switch(i){
            case TYPE_SIMPLELIST:Log.d("kbt","ADAP STAR ONCR first switch");
                View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerlist_item, viewGroup, false);
                VersionViewHolder viewHolder = new VersionViewHolder(view);
                return viewHolder;

            case TYPE_JSONLIST:Log.d("kbt","ADAP STAR ONCR second switch");
                View view2 = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerlist2_item, viewGroup, false);
                Log.d("kbt","ADAP STAR ONCR second switch 2nd line");
                JSONHolder viewHolder2 = new JSONHolder(view2);
                Log.d("kbt","ADAP STAR ONCR second switch 3nd line");
                return viewHolder2;


        }
        return null;

    }

    @Override
    public void onBindViewHolder(MainViewHolder holder, int i) {

        switch (holder.getItemViewType()){
            case TYPE_SIMPLELIST:Log.d("kbt","ONBIND First switch start");
                VersionViewHolder versionViewHolder=(VersionViewHolder)holder;
                if (isHomeList) {
                    versionViewHolder.title.setText(homeActivitiesList.get(i));
                    versionViewHolder.subTitle.setText(homeActivitiesSubList.get(i));
                } else {
                    versionViewHolder.title.setText(versionModels.get(i));
                }Log.d("kbt","ONBIND First switch end");
                break;
            case TYPE_JSONLIST:Log.d("kbt","ONBIND second switch start");
                JSONHolder jsonHolder=(JSONHolder)holder;
                Log.d("kbt","ONBIND second switch premiddle");
                FeedItem feedItem = feedItemList.get(i);
                Log.d("kbt","ONBIND second switch middle");
                Picasso.with(mContext).load(feedItem.getThumbnail())
                        .error(R.drawable.placeholder)
                        .placeholder(R.drawable.placeholder)
                        .into(jsonHolder.thumbnail);
                Log.d("kbt", "ONBIND second switch 2nd middle");
                jsonHolder.title.setText(Html.fromHtml(feedItem.getTitle()));
                Log.d("kbt", "ONBIND second switch end");


        }

    }

    @Override
    public int getItemCount() {
        if(isJson){
            return (null != feedItemList ? feedItemList.size() : 0);
        }
        else{
            if (isHomeList)
                return homeActivitiesList == null ? 0 : homeActivitiesList.size();
            else
                return versionModels == null ? 0 : versionModels.size();
        }

    }


    class VersionViewHolder extends MainViewHolder implements View.OnClickListener {
        CardView cardItemLayout;
        TextView title;
        TextView subTitle;


        public VersionViewHolder(View itemView) {
            super(itemView);

            rv=(RecyclerView)itemView.findViewById(R.id.dummyfrag_scrollableview);

            cardItemLayout = (CardView) itemView.findViewById(R.id.cardlist_item);
            title = (TextView) itemView.findViewById(R.id.listitem_name);
            subTitle = (TextView) itemView.findViewById(R.id.listitem_subname);

            if (isHomeList) {
                itemView.setOnClickListener(this);
                Log.d("kbt","Inside first");
            } else {
                subTitle.setVisibility(View.GONE);
                /*View.GONE This view is invisible, and it doesn't take any space for layout purposes.
                  View.INVISIBLE This view is invisible, but it still takes up space for layout purposes.*/
            }

        }

        @Override
        public void onClick(View v) {
            Log.d("kbt", "Inside second first");
           clickListener.onItemClick(v,getAdapterPosition());
            Log.d("kbt", "Inside second");

        }

    }

    public interface OnItemClickListener {
        void onItemClick(View view, int position);


    }

    public void SetOnItemClickListener(final OnItemClickListener itemClickListener) {
        this.clickListener = itemClickListener;


    }

    class JSONHolder extends MainViewHolder {

        protected ImageView thumbnail;
        protected TextView title;
        public JSONHolder(View itemView) {
            super(itemView);
            Log.d("kbt","JSON Inside HOLDER");
            rv=(RecyclerView)itemView.findViewById(R.id.jsonrecyclerview);
            thumbnail = (ImageView) itemView.findViewById(R.id.thumbnail);
            title = (TextView) itemView.findViewById(R.id.title);


            }

        }


    public class MainViewHolder extends  RecyclerView.ViewHolder {
       public MainViewHolder(View v) {
        super(v);
       }
    }

    }

Error :

11-13 14:36:43.645  21502-21502/? I/Process﹕ Sending signal. PID: 21502 SIG: 9
11-13 14:36:43.645  21502-21502/? D/AndroidRuntime﹕ procName from cmdline: corp.trees.com.mdesign
11-13 14:36:43.645  21502-21502/? E/AndroidRuntime﹕ in writeCrashedAppName, pkgName :corp.trees.com.mdesign
11-13 14:36:43.645  21502-21502/? D/AndroidRuntime﹕ file written successfully with content: corp.trees.com.mdesign StringBuffer : ;corp.trees.com.mdesign
11-13 14:36:43.645  21502-21502/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: corp.trees.com.mdesign, PID: 21502
    java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
            at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
            at java.util.ArrayList.get(ArrayList.java:308)
            at corp.trees.com.mdesign.SimpleRecyclerAdapter.onBindViewHolder(SimpleRecyclerAdapter.java:108)
            at corp.trees.com.mdesign.SimpleRecyclerAdapter.onBindViewHolder(SimpleRecyclerAdapter.java:21)
            at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5084)
            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4385)
            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4278)
            at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1947)
            at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1359)
            at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1322)
            at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:556)
            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2673)
            at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2971)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1626)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1009)
            at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:719)
            at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
            at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:984)
            at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:732)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:907)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
            at android.view.View.layout(View.java:14852)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1994)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1751)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1007)
            at android.view.ViewRootImpl$T
8
  • 2
    I don't know if this might be the problem, but HttpPost uses the POST method, and the URL you are trying to fetch throws a 404 when using POST method. Commented Nov 13, 2015 at 8:21
  • 1
    Indeed. So the GET method or HttpGet should be used instead. Commented Nov 13, 2015 at 8:41
  • @greenapps I tried HttpGet and same problem remains :( Commented Nov 13, 2015 at 8:43
  • 1
    Your only problem is that you use this json parser class which does not provide you info if the requested text is not json or cannot be grabbed. In this case you got a 404 html text and not json. So if this parser is then blindly parsing this html it goes wrong. You should first add some code to that class so the user knows that the page could not be retrieved. After that do as you were advised. Commented Nov 13, 2015 at 8:51
  • 1
    Looks like your code is reaching the adapter. Could you post your SimpleRecyclerAdapter? Commented Nov 13, 2015 at 10:10

2 Answers 2

1

I see many weird things in your adapter, correct me if I am wrong but

According to the documentation getItemCount() must return the total number of items that the adapter holds. In your adapter you are using multiple lists and getItemCount() is returning one's size depending on some variables, but getItemCount() will be called only once by the recycler view, so this will only work if you use only one of those lists per SimpleRecyclerAdapter instance. You are only initializing feedItemList, the other lists remain null or empty. So I'm gonna presume this is what you are trying to do.

But when getting the current elementType you use:

    @Override
    public int getItemViewType(int position) {
        return position == 0 ? TYPE_SIMPLELIST : TYPE_JSONLIST;
    }

This means your first element will be a TYPE_SIMPLELIST and the others will be TYPE_JSONLIST. This does not make sense to me, because only one of your lists is initialized (feedItemList), so I think you should return something like:

    @Override
    public int getItemViewType(int position) {
        return isJson? TYPE_JSONLIST : TYPE_SIMPLELIST;
    }

So it always reads data from feedItemList.

Sign up to request clarification or add additional context in comments.

4 Comments

Exactly, My first element was from TYPE_SIMPLELIST and rest are from JSON. I was in confusion why the heck it came like that. I read Documentation but i didn't got clear idea about this getItemViewType, Can you explan in more detail about this getItemViewType(position) what this position value will be? You got the correct point, but still i am in confusion why that list printed like that.
getItemViewType is called for every item in the list, the position value is the number of the item the RecyclerView wants (from 0 to getItemCount()). If you want the first element to be TYPE_SIMPLELIST and the rest of the elements TYPE_JSONLIST, then your code is correct. Another thing I noticed is that in your onBindViewHolder you are calling holder.getItemViewType() That holder is an instance of MainViewHolder but you never override getItemViewType in that class.
Thankyou so much... I was always in confusin even after referring many website tutorials, but you cleared my doubts. :) Thank you so much... Could you provide your email or something so that i can ask you help for my next question in Stack Overflow. :)
I'm sorry but I can't. Don't worry, this is a big community, I'm sure people will be happy to help.
1

I think you better use GET method instead of POST, and try HttpURLConnection, here is a sample:

URL requestUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)requestUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();

2 Comments

Hi @Inso , Thanks for your help. But I used HttpURLConnection only at starting. What problem i faced is, After this line "HttpURLConnection conn = (HttpURLConnection)requestUrl.openConnection();" my program flow is not moving. I checked with Log.d by specifying above and below that line.
@Ganesh, Have you tired to add a line to getResponseCode()? if the ResponseCode is not 200, then you can't receive response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.