0

I've been working on a feature that on my app that requires inserting and retrieving data from SQLite. So far, the inserting portion of the feature is working (the database and the tables are created and they have values) but the retrieval does not. I have an NPE that says that I invoked the RecyclerView on a null object reference. Then the app crashes. I have provided my codes below. Any help, please? Thank you!

fetchAllSavedNews() method:

public ArrayList<News> fetchAllSavedNews() {
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.query(TABLE_NAME, allColumns,
                null,null,null, null, KEY_DATE + " DESC");

        ArrayList<News> newsList = new ArrayList<>();
        if(cursor.getCount() > 0) while (cursor.moveToNext()) {
            int index0 = cursor.getColumnIndex(KEY_ID);
            int index1 = cursor.getColumnIndex(KEY_SERVER_ID);
            int index2 = cursor.getColumnIndex(KEY_TITLE);
            int index3 = cursor.getColumnIndex(KEY_IMAGE);
            int index4 = cursor.getColumnIndex(KEY_CATEGORY);
            int index5 = cursor.getColumnIndex(KEY_CONTENT);
            int index6 = cursor.getColumnIndex(KEY_AUTHOR);
            int index7 = cursor.getColumnIndex(KEY_DATE);

            int id = cursor.getInt(index0);
            int server_id = cursor.getInt(index1);
            String title = cursor.getString(index2);
            byte[] imageByteArray = cursor.getBlob(index3);
            Bitmap imageBitmap = BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length);
            String category = cursor.getString(index4);
            String content = cursor.getString(index5);
            String author = cursor.getString(index6);
            String publicationDate = cursor.getString(index7);

            News savedNewsArrayList = new News(id, server_id, title, imageBitmap, category, content, author, publicationDate);
            newsList.add(savedNewsArrayList);
        }
        // return All Employees
        return newsList;
    }

Fragment

public class FavoriteNewsFragment extends Fragment implements ConnectivityReceiver.ConnectivityReceiverListener {

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

    final String TAG = "MainPageActivity";
    DatabaseHelper myDb;
    public RecyclerView rvSavedNews;
    public SavedNewsArticleAdapter adapter;
    public SwipeRefreshLayout swipeRefreshLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view =  inflater.inflate(R.layout.fragment_favorite_news, container, false);

        myDb = new DatabaseHelper(getActivity());

        checkConnection();

        rvSavedNews = (RecyclerView) view.findViewById(R.id.rvSavedNews);
        rvSavedNews.setHasFixedSize(true);
        final LinearLayoutManager manager = new LinearLayoutManager(getActivity());
        rvSavedNews.setLayoutManager(manager);
        rvSavedNews.setItemAnimator(new DefaultItemAnimator());


        swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefresh);
        swipeRefreshLayout.setColorSchemeResources(R.color.primaryColor, R.color.primaryTextColor, R.color.secondaryColor);
        swipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        loadSavedNews();
                    }
                }, 1000);
            }
        });

        return view;
    }

    private void loadSavedNews() {
        adapter = new SavedNewsArticleAdapter(getActivity(), myDb.fetchAllSavedNews());
        rvSavedNews.setAdapter(adapter);
        swipeRefreshLayout.setRefreshing(false);
    }

    // Method to manually check connection status
    private void checkConnection() {
        boolean isConnected = isConnected();
        snackInternet(isConnected);
    }

    private void snackInternet(boolean isConnected) {
        if (isConnected) {
            Snackbar snackbar = Snackbar.make(getActivity().findViewById(android.R.id.content), "Connected to the Internet!", Snackbar.LENGTH_SHORT);
            View sbView = snackbar.getView();
            sbView.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.primaryDarkColor));
            snackbar.show();
            loadSavedNews();
        }
        else {
            Snackbar snackbar = Snackbar
                    .make(getActivity().findViewById(android.R.id.content), "You seem to be offline.", Snackbar.LENGTH_INDEFINITE)
                    .setAction("Retry", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            loadSavedNews();
                        }
                    });
            View sbView = snackbar.getView();
            sbView.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.maroon));
            snackbar.show();
            loadSavedNews();
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        // register connection status listener
        TheFlare.getInstance().setConnectivityListener(this);
    }

    /**
     * Callback will be triggered when there is change in
     * network connection
     */
    @Override
    public void onNetworkConnectionChanged(boolean isConnected) {
        snackInternet(isConnected);
    }

}

Adapter

public class SavedNewsArticleAdapter extends RecyclerView.Adapter<SavedNewsArticleAdapter.SavedNewsViewHolder> {

    private Context context;
    private ArrayList<News> savedNews;

    public SavedNewsArticleAdapter(Context context, ArrayList<News> savedNews){
        this.context = context;
        this.savedNews = savedNews;
    }

    @Override
    public SavedNewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.from(parent.getContext())
                .inflate(R.layout.news_cardview_layout, parent, false);

        SavedNewsViewHolder savedNewsViewHolder = new SavedNewsViewHolder(view);
        return savedNewsViewHolder;
    }

    @Override
    public void onBindViewHolder(SavedNewsViewHolder holder, int position) {
        final News selectedSavedNews = savedNews.get(position);
        holder.tvId.setText(String.valueOf(selectedSavedNews.getId()));
        holder.tvTitle.setText(selectedSavedNews.getTitle());
        holder.tvPubDate.setText("" + selectedSavedNews.getPublicationDate());

        Picasso.with(context)
                .load(selectedSavedNews.getImgBanner())
                .placeholder(R.drawable.bannerplaceholder)
                .error(android.R.drawable.stat_notify_error)
                .into(holder.ivImage);

        holder.ivImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View view) {
                Intent intent = new Intent(context, SavedNewsDetailActivity.class);
                intent.putExtra("savedNews", selectedSavedNews);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() {
        if(savedNews != null){
            return savedNews.size();
        }
        return 0;
    }

    //ViewHolder class
    public static class SavedNewsViewHolder extends RecyclerView.ViewHolder{

        public CardView cvNews;
        public TextView tvId;
        public ImageView ivImage;
        public TextView tvTitle;
        public TextView tvPubDate;

        public SavedNewsViewHolder(View itemView) {
            super(itemView);
            cvNews = (CardView)itemView.findViewById(R.id.cvNews);
            tvId = (TextView) itemView.findViewById(R.id.tvId);
            ivImage = (ImageView)itemView.findViewById(R.id.ivImageUrl);
            tvTitle = (TextView)itemView.findViewById(R.id.tvTitle);
            tvPubDate = (TextView)itemView.findViewById(R.id.tvPubDate);

        }
    }
}

NPE

E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: com.cvsuimus.theflare, PID: 23967
                                                   java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)' on a null object reference
                                                       at com.cvsuimus.theflare.FavoriteNewsFragment.loadSavedNews(FavoriteNewsFragment.java:67)
                                                       at com.cvsuimus.theflare.FavoriteNewsFragment.snackInternet(FavoriteNewsFragment.java:83)
                                                       at com.cvsuimus.theflare.FavoriteNewsFragment.checkConnection(FavoriteNewsFragment.java:74)
                                                       at com.cvsuimus.theflare.FavoriteNewsFragment.onCreateView(FavoriteNewsFragment.java:38)
Matthew Miranda
  • 138
  • 1
  • 3
  • 15
  • You're calling `checkConnection()` – which chain calls a couple other methods that eventually call `rvSavedNews.setAdapter()` – before you've assigned `rvSavedNews`. Move it to after the `rvSavedNews` and `swipeRefreshLayout` setup in `onCreateView()`, to right before `return view;`. – Mike M. Feb 09 '18 at 06:43
  • It worked! Thanks, @MikeM.! How can I vote for your answer up? – Matthew Miranda Feb 09 '18 at 06:57
  • @MatthewMiranda You can not vote – Gowthaman M Feb 09 '18 at 06:59
  • Ah, cool. Actually, it's a common issue; calling a method on a null. I've already marked it as a duplicate, so no worries. Glad you got it working. Cheers! – Mike M. Feb 09 '18 at 07:02

0 Answers0