2

In recyclerview , some time it shows the output on the first execution and sometimes, it shows the output on the second or third time... and the worst thing is, some time it doesn't show any data at all. The links from which I am getting data are working fine. Can somebody tell me where I am making mistakes. I have seen the other answer regarding this problem but didn't work for me!

Here is the adapter code

    private LayoutInflater inflater;
    Context context;
    List<Data> dataArray;

    public RecyclerViewAdapter(Context context, List<Data> dataArray) {
        this.dataArray = dataArray;
        this.context = context;
        inflater = LayoutInflater.from(context);
    }


    @Override
    public RecyclerViewAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, null);
        //View view = inflater.inflate(R.layout.cardview, parent, false);
        CustomViewHolder holder = new CustomViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(CustomViewHolder holder, int position) {
        Data current = dataArray.get(position);
        //holder.image.setImageResource(current.Limage);
        holder.textView1.setText(current.heading);
        holder.textView2.setText(current.date);
        holder.textView3.setText(current.brief);

    }

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

    public static class CustomViewHolder extends RecyclerView.ViewHolder {
        //ImageView image;
        TextView textView1, textView2, textView3;

        public CustomViewHolder(View itemView) {
            super(itemView);
            // image = (ImageView)itemView.findViewById(R.id.Limage);
            textView1 = (TextView) itemView.findViewById(R.id.heading);
            textView2 = (TextView) itemView.findViewById(R.id.date);
            textView3 = (TextView) itemView.findViewById(R.id.brief);


        }
    }

And here is my JSON class

    Context context;
    public static List<Data> dataArray = new ArrayList<>();


    public JSONAsync(Context context) {
        this.context = context;
        dataArray.clear();

    }

    @Override
    protected Boolean doInBackground(String... params) {

        try {
            return downloadUrl(params[0]);
        } catch (IOException e) {
            return false;
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    public boolean downloadUrl(String myurl) throws IOException, JSONException {
        InputStream is = null;
        int response;

        try {
            URL url = new URL(myurl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.connect();
            response = conn.getResponseCode();
            is = conn.getInputStream();
            if (response == 200) {
                String responseBody = convertToString(conn.getInputStream());
                JSONArray jArray = new JSONArray(responseBody);

                //  JSONArray jArray = new JSONArray(is);
                for (int i = 0; i < jArray.length(); i++) {
                    JSONObject jobj = jArray.getJSONObject(i);
                    Data data = new Data();
                    data.setId(jobj.getInt("id"));
                    data.setHeading(jobj.getString("heading"));
                    data.setBrief(jobj.getString("brief"));
                    data.setDate(jobj.getString("date"));
                    dataArray.add(data);
                }
            recyclerViewAdapter.notifyDataSetChanged();
                return true;
            } else return false;

        } finally {
            if (is != null) {
                is.close();
            }
        }

    }

    public String convertToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
        } catch (IOException e) {
        } finally {
            try {
                is.close();
            } catch (IOException e) {
            }
        }

        return sb.toString();
    }

    @Override
    protected void onPostExecute(Boolean result) {

        if (result == false) {
            Toast.makeText(context, "Unable to fetch data from server", Toast.LENGTH_SHORT).show();
        }
    }

And here is the activity code in which I am displaying data

    Toolbar toolbar;
    public RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //overridePendingTransition(R.anim.fadein, R.anim.fadeout);
        setContentView(R.layout.activity_main_news);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Get Request
        String url = "MY URL NOT SHOWING HERE INTENTIONALLY";
        new JSONAsync(getApplicationContext()).execute(url);

        // Initializing the Recycler View and its layout
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(MainNews.this, JSONAsync.dataArray);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(recyclerViewAdapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerViewAdapter.notifyDataSetChanged();
        //recyclerView.setHasFixedSize(true);
    }

And here is the XML layout I am using

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/Relative"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFD4CBCB"
    tools:context="admin.myproject.MainNews">

    <include layout="@layout/toolbar" />

    <LinearLayout
        android:id="@+id/Linear1"
        style="@style/AlertDialog.AppCompat.Light"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        android:orientation="vertical"
        android:layout_centerHorizontal="true">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="true"
            android:text="Main Section"
            android:textIsSelectable="true"
            android:textSize="30dp" />
    </LinearLayout>

    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@id/Linear1"
        android:background="@android:color/darker_gray" />

    <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/view" />

</RelativeLayout>

There are several activities using the same pattern ... Sometimes, it shows the data as described and on the other times, it doesn't. Any help would be highly appreciated.

Edited: After using the recyclerViewAdapter.notifyDataSetChanged(), I am getting the NPE. Any suggestion of how to get rif of this method.

Complete LogCat after adding notifyDataSetChanged() is:

FATAL EXCEPTION: AsyncTask #1 Process: admin.myproject, PID: 27693 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:309) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) at java.util.concurrent.FutureTask.setException(FutureTask.java:223) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void admin.myproject.RecyclerViewAdapter.notifyDataSetChanged()' on a null object reference at admin.myproject.JSONAsync.downloadUrl(JSONAsync.java:76) at admin.myproject.JSONAsync.doInBackground(JSONAsync.java:40) at admin.myproject.JSONAsync.doInBackground(JSONAsync.java:23) at android.os.AsyncTask$2.call(AsyncTask.java:295) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)  at java.lang.Thread.run(Thread.java:818) 

Cœur
  • 37,241
  • 25
  • 195
  • 267
Umair
  • 438
  • 1
  • 8
  • 19

2 Answers2

5

Set the adapter for recycle view.

LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
RecycleViewAdapter adapter = new RecycleViewAdapter(list);
recycleView.setLayoutManager(layoutManager);
recycleView.setHasFixedSize(true);
recycleView.setAdapter(adapter);

Then in your Async task every time you add a value to dataArray or List use

adapter.notifyItemInserted(list.size());

Set the adapter for the recycle view before executing the async task.

0

You must set your adapter in the postExecute of your AsyncTask when you have fetched your data from Json so it will look like

And here is my JSON class


Context context;
public static List<Data> dataArray = new ArrayList<>();


public JSONAsync(Context context) {
    this.context = context;
    dataArray.clear();

}

@Override
protected Boolean doInBackground(String... params) {

    try {
        return downloadUrl(params[0]);
    } catch (IOException e) {
        return false;
    } catch (JSONException e) {
        e.printStackTrace();
    }

    return null;
}

public boolean downloadUrl(String myurl) throws IOException, JSONException {
    InputStream is = null;
    int response;

    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();
        response = conn.getResponseCode();
        is = conn.getInputStream();
        if (response == 200) {
            String responseBody = convertToString(conn.getInputStream());
            JSONArray jArray = new JSONArray(responseBody);

            //  JSONArray jArray = new JSONArray(is);
            for (int i = 0; i < jArray.length(); i++) {
                JSONObject jobj = jArray.getJSONObject(i);
                Data data = new Data();
                data.setId(jobj.getInt("id"));
                data.setHeading(jobj.getString("heading"));
                data.setBrief(jobj.getString("brief"));
                data.setDate(jobj.getString("date"));
                dataArray.add(data);
            }
            return true;
        } else return false;

    } finally {
        if (is != null) {
            is.close();
        }
    }

}

public String convertToString(InputStream is) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("\n");
        }
    } catch (IOException e) {
    } finally {
        try {
            is.close();
        } catch (IOException e) {
        }
    }

    return sb.toString();
}

@Override
protected void onPostExecute(Boolean result) {

    if (result == false) {
        Toast.makeText(context, "Unable to fetch data from server", Toast.LENGTH_SHORT).show();
    }else{
    recyclerViewAdapter = new RecyclerViewAdapter(MainNews.this,     JSONAsync.dataArray);
    recyclerView.setAdapter(recyclerViewAdapter);
         }
}
Helmi
  • 90
  • 5