-3

Now I trying to create a book app using sqlite and this is my first time to using it. but there are a problem when i get the data from the cursor.

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ar.team.company.app.ar_app_08, PID: 18302
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ar.team.company.app.ar_app_08/com.ar.team.company.app.ar_app_08.HomeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor com.ar.team.company.app.ar_app_08.controller.ARDatabaseHelper.getBooks()' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor com.ar.team.company.app.ar_app_08.controller.ARDatabaseHelper.getBooks()' on a null object reference
    at com.ar.team.company.app.ar_app_08.HomeActivity.storeDataInArray(HomeActivity.java:58)
    at com.ar.team.company.app.ar_app_08.HomeActivity.onCreate(HomeActivity.java:39)
    at android.app.Activity.performCreate(Activity.java:8000)
    at android.app.Activity.performCreate(Activity.java:7984)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:223) 
    at android.app.ActivityThread.main(ActivityThread.java:7656) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

HomeActivity:

package com.ar.team.company.app.ar_app_08;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.recyclerview.widget.LinearLayoutManager;

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.ar.team.company.app.ar_app_08.adapters.BooksAdapter;
import com.ar.team.company.app.ar_app_08.controller.ARDatabaseHelper;
import com.ar.team.company.app.ar_app_08.databinding.ActivityHomeBinding;
import com.ar.team.company.app.ar_app_08.model.Book;
import com.google.android.material.snackbar.Snackbar;

import java.util.ArrayList;

@SuppressWarnings("FieldCanBeLocal")
public class HomeActivity extends AppCompatActivity {

    // This For Control The XML-Main Views:
    private ActivityHomeBinding binding;
    private ARDatabaseHelper helper;
    private BooksAdapter adapter;
    private ArrayList<Book> books;
    private ArrayList<String> id;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityHomeBinding.inflate(getLayoutInflater()); // INFLATE THE LAYOUT.
        View view = binding.getRoot(); // GET ROOT [BY DEF(CONSTRAINT LAYOUT)].
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        setContentView(view); // SET THE VIEW CONTENT TO THE (VIEW).
        // Store the data:
        storeDataInArray();
        // Initialize:
        helper = new ARDatabaseHelper(this);
        books = new ArrayList<>();
        id = new ArrayList<>();
        adapter = new BooksAdapter(this, books, id, binding.parentHomeLayout);
        // Developing the new activity fab:
        binding.newBookFloatingActionButton.setOnClickListener(this::launchNewBookActivity);
        // Developing the recycler view:
        binding.booksRecyclerView.setAdapter(adapter);
        binding.booksRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    private void launchNewBookActivity(View view) {
        Intent newBookActivity = new Intent(this, NewBookActivity.class);
        startActivity(newBookActivity);
    }

    private void storeDataInArray() {
        Cursor cursor = helper.getBooks();
        if (cursor.getCount() == 0) {
            Snackbar.make(binding.parentHomeLayout, "No data.", Snackbar.LENGTH_LONG)
                    .setAction("Close", v -> Log.i("SnackBar_Click", "Closed")).show();
        }else {
            cursor.moveToFirst();
            while (cursor.moveToNext()) {
                String bookID = cursor.getString(0);
                String bookTitle = cursor.getString(1);
                String bookAuthor = cursor.getString(2);
                int bookPages = Integer.parseInt(cursor.getString(3));
                books.add(new Book(bookTitle, bookAuthor, bookPages));
                id.add(bookID);
            }
        }
    }

}

NewBookActivity:

package com.ar.team.company.app.ar_app_08;

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;

import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.ar.team.company.app.ar_app_08.controller.ARDatabaseHelper;
import com.ar.team.company.app.ar_app_08.databinding.ActivityNewBookBinding;
import com.ar.team.company.app.ar_app_08.model.Book;
import com.google.android.material.snackbar.Snackbar;

import java.util.ArrayList;
import java.util.Objects;

@SuppressWarnings("FieldCanBeLocal")
public class NewBookActivity extends AppCompatActivity {

    // This For Control The XML-Main Views:
    private ActivityNewBookBinding binding;
    private ARDatabaseHelper helper;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityNewBookBinding.inflate(getLayoutInflater()); // INFLATE THE LAYOUT.
        View view = binding.getRoot(); // GET ROOT [BY DEF(CONSTRAINT LAYOUT)].
        setContentView(view); // SET THE VIEW CONTENT TO THE (VIEW).
        // Initialize:
        helper = new ARDatabaseHelper(this);
        // Developing the new book button:
        binding.newBookButton.setOnClickListener(this::createNewBook);
    }

    private void createNewBook(View view) {
        String bookTitle = Objects.requireNonNull(binding.bookTitleEditText.getText()).toString();
        String bookAuthor = Objects.requireNonNull(binding.bookAuthorEditText.getText()).toString();
        int bookPages = Integer.parseInt(Objects.requireNonNull(binding.bookPagesEditText.getText()).toString());
        Book book = new Book(bookTitle, bookAuthor, bookPages);
        helper.newBook(book, binding.parentNewBookLayout);
    }




}

BooksAdapter:

package com.ar.team.company.app.ar_app_08.adapters;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;

import com.ar.team.company.app.ar_app_08.R;
import com.ar.team.company.app.ar_app_08.model.Book;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.snackbar.Snackbar;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;

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

    private final Context context;
    private final ArrayList<Book> books;
    private final ArrayList<String> id;
    private final ConstraintLayout layout;

    public BooksAdapter(Context context, ArrayList<Book> books, ArrayList<String> id, ConstraintLayout layout) {
        this.context = context;
        this.books = books;
        this.id = id;
        this.layout = layout;
        notifyDataSetChanged();
    }

    @NotNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.books_row, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull @NotNull BooksAdapter.ViewHolder holder, int position) {
        holder.id.setText(id.get(position));
        holder.title.setText(books.get(position).getBookTitle());
        holder.author.setText(books.get(position).getBookAuthor());
        holder.pages.setText(books.get(position).getBookPages());
        holder.cardView.setOnClickListener(v -> {
            Snackbar.make(layout, books.get(position).getBookTitle(), Snackbar.LENGTH_LONG)
                    .setAction("Close", v1 -> Log.i("SnackBar_Click", "Closed")).show();
        });
    }

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

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final MaterialCardView cardView;
        private final TextView id, title, author, pages;

        public ViewHolder(@NonNull @org.jetbrains.annotations.NotNull View itemView) {
            super(itemView);
            cardView = itemView.findViewById(R.id.cardView);
            id = itemView.findViewById(R.id.book_id_text_view);
            title = itemView.findViewById(R.id.book_title_text_view);
            author = itemView.findViewById(R.id.book_author_text_view);
            pages = itemView.findViewById(R.id.book_pages_text_view);
        }
    }
}

ARDatabaseHelper:

package com.ar.team.company.app.ar_app_08.controller;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.ar.team.company.app.ar_app_08.model.Book;
import com.ar.team.company.app.ar_app_08.utils.ARUtils;
import com.google.android.material.snackbar.Snackbar;

    public class ARDatabaseHelper extends SQLiteOpenHelper {

        private final Context context;

        public ARDatabaseHelper(@Nullable Context context) {
            super(context, ARUtils.DATABASE_FILE_NAME, null, ARUtils.DATABASE_VERSION);
            this.context = context;
        }

        public Context getContext() {
            return context;
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            String tN = ARUtils.DATABASE_TABLE_NAME;
            String id = ARUtils.COLUMN_ID;
            String bT = ARUtils.COLUMN_TITLE;
            String bA = ARUtils.COLUMN_AUTHOR;
            String bP = ARUtils.COLUMN_PAGES;
            String query = "CREATE TABLE " + tN +
                    "(" + id + " INTEGER PRIMARY KEY AUTOINCREMENT, " + bT + " TEXT, " + bA + " TEXT, " + bP + " TEXT )";
            db.execSQL(query);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + ARUtils.DATABASE_TABLE_NAME);
            onCreate(db);
        }

        public void newBook(Book book, ConstraintLayout layout) {
            // Initialize database:
            SQLiteDatabase db = this.getWritableDatabase();
            ContentValues values = new ContentValues();
            // Put the values:
            values.put(ARUtils.COLUMN_TITLE, book.getBookTitle());
            values.put(ARUtils.COLUMN_AUTHOR, book.getBookAuthor());
            values.put(ARUtils.COLUMN_PAGES, book.getBookPages());
            // Finishing:
            long res = db.insert(ARUtils.DATABASE_TABLE_NAME, null, values);
            if (res == -1) showSnackBar("Failed to create new book.", layout);
            else showSnackBar("Successfully created new book.", layout);
        }

        public Cursor getBooks() {
            // Initialize database:
            SQLiteDatabase db = this.getReadableDatabase();
            Cursor cursor = null;
            if (db != null) {
                cursor = db.rawQuery("SELECT * FROM " + ARUtils.DATABASE_TABLE_NAME, null);
            }
            return cursor;
        }

        public void showSnackBar(String mes, ConstraintLayout layout) {
            Snackbar.make(layout, mes, Snackbar.LENGTH_LONG)
                    .setAction("Close", v -> Log.i("SnackBar_Click", "Closed")).show();
        }

}
MikeT
  • 51,415
  • 16
  • 49
  • 68
ABDO-AR
  • 160
  • 3
  • 9
  • 1
    You need to learn to debug your app. – juergen d Jul 07 '21 at 04:37
  • Thanks for the advice but this is the first time to work with the SQLite so because that I don't know where exactly the problem – ABDO-AR Jul 07 '21 at 05:01
  • Look at the error message. See the line that causes the problem. It is line 58. You call `helper.getBooks();` while `helper` is still null. If you debug that you can see it clearly. Please take a tutorial on that. You will get nowhere without debugging – juergen d Jul 07 '21 at 05:28
  • ohh thanks but please if you have an any tutorial on debugging please send me a link and thanks – ABDO-AR Jul 07 '21 at 06:39

1 Answers1

0

You are calling the storeDataInArray method before getting (initialising) the helper instance so helper is null.

So when the attempt is made to execute the line Cursor cursor = helper.getBooks(); you get the NPE because helper is null. The log is telling you this when it says :-

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor com.ar.team.company.app.ar_app_08.controller.ARDatabaseHelper.getBooks()' on a null object reference
at com.ar.team.company.app.ar_app_08.HomeActivity.storeDataInArray(HomeActivity.java:58)

Instead of :-

    // Store the data:
    storeDataInArray();
    // Initialize:
    helper = new ARDatabaseHelper(this);

use :-

    // Initialize:
    helper = new ARDatabaseHelper(this);
    // Store the data:
    storeDataInArray();
MikeT
  • 51,415
  • 16
  • 49
  • 68
  • oh man I laugh at myself ... sorry I was tired because this is the first time work with SQLite so thanks no no really thanks ... you know I'm very beginner in android so if you can give any path to learn it perfect because I have some problems of find the best course i have an 16 years old from Egypt so you know our country don't support developers too much and thanks – ABDO-AR Jul 07 '21 at 06:45