0

I am new to programming thats why I dont understand the Info to What is a NullPointerException, and how do I fix it? .

I wrote a app, where you read the isbn of a book and you will get the bookinfo, bookimage via googlebooksAPI.

I managed that the data inclusive the image will be stored in the sqlite db. I want to display the stored data in a listview. (I managed it before, but without storing the image - no Nullpointer error). There I get the error.

unfortunately I got this error: java.lang.NullPointerException: Attempt to get length of null array

Following my Logcat und the used Activities:

Logcat:

Process: com.kasutwentyseven.gui4selfshelf, PID: 32327
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kasutwentyseven.gui4selfshelf/com.kasutwentyseven.gui4selfshelf.Books.BookDataListActivity}: java.lang.NullPointerException: Attempt to get length of null array
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2357)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2419)
at android.app.ActivityThread.access$900(ActivityThread.java:154)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5291)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at com.kasutwentyseven.gui4selfshelf.Books.BookDataListActivity.onCreate(BookDataListActivity.java:130)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2310)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2419) 
at android.app.ActivityThread.access$900(ActivityThread.java:154) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5291) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 

I think the error is in the onCreate method of the BookDataListActivity

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.book_data_list_layout);

    Typeface myTypeface = Typeface.createFromAsset(getAssets(), "Lobster.ttf");

    TextView myTextView = (TextView) findViewById(R.id.text_yourbooks);
    myTextView.setTypeface(myTypeface);

    booklistView = (ListView) findViewById(R.id.book_list_view);
    inputSearch = (EditText) findViewById(R.id.search_bar);

    bookListDataAdapter = new BookListDataAdapter(getApplicationContext(), R.layout.row_book_layout);
    booklistView.setAdapter(bookListDataAdapter);


    //onItemClickListener
    booklistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            Intent intent = new Intent(getApplicationContext(), BookInfoActivity.class);



            editTextBooktitle = (TextView) view.findViewById(R.id.text_book_title);
            String book_title = editTextBooktitle.getText().toString();
            intent.putExtra(EXTRA_MSG1, book_title);

            editTextBookauthor = (TextView) view.findViewById(R.id.text_book_author);
            String bookauthor = editTextBookauthor.getText().toString();
            intent.putExtra(EXTRA_MSG2, bookauthor);

            editTextBookdate = (TextView) view.findViewById(R.id.text_book_date);
            String bookdate = editTextBookdate.getText().toString();
            intent.putExtra(EXTRA_MSG3, bookdate);

            editTextBookrating = (TextView) view.findViewById(R.id.text_book_rating);
            String bookrating = editTextBookrating.getText().toString();
            intent.putExtra(EXTRA_MSG4, bookrating);

            editTextBookshelf = (TextView) view.findViewById(R.id.text_book_shelf);
            String bookshelf = editTextBookshelf.getText().toString();
            intent.putExtra(EXTRA_MSG5, bookshelf);

            startActivity(intent);

        }

    });


    inputSearch.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            bookListDataAdapter.getFilter().filter(s);
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

    bookDBHelper = new BookDBHelper(getApplicationContext());
    sqLiteDatabaseBooks = bookDBHelper.getReadableDatabase();
    cursor2 = bookDBHelper.getInformations(sqLiteDatabaseBooks);
    if (cursor2.moveToFirst()) {
        do {
            String booktitle, bookauthor, bookdate, bookrating, bookshelf;
            Bitmap bookimage;

            byte[] blob= cursor2.getBlob(0);
            bookimage = BitmapFactory.decodeByteArray(blob,0,blob.length);
            booktitle = cursor2.getString(1);
            bookauthor = cursor2.getString(2);
            bookdate = cursor2.getString(3);
            bookrating = cursor2.getString(4);
            bookshelf = cursor2.getString(5);

            BookDataProvider bookDataProvider = new BookDataProvider(bookimage, booktitle, bookauthor, bookdate, bookrating, bookshelf);
            bookListDataAdapter.add(bookDataProvider);

        } while (cursor2.moveToNext());
    }
}

}

I think you will need the methods for adding and getting the Info data for the listview - It is in the BOOKDBHelper Activity

public class BookDBHelper extends SQLiteOpenHelper{

private static final String DATABASE_BOOKS_NAME = "BookINFO.DB";
private static final int DATABASE_BOOKS_VERS = 2;
private static final String CREATE_QUERY_BOOKS =
        "CREATE TABLE "
                + BookContent.NewBookInfo.TABLE_NAME_BOOKS
                +"("
                + BookContent.NewBookInfo.BOOK_IMAGE +" BLOB, "
                + BookContent.NewBookInfo.BOOK_TITLE+" TEXT, "
                + BookContent.NewBookInfo.BOOK_AUTHOR+" TEXT, "
                + BookContent.NewBookInfo.BOOK_DATE+" TEXT, "
                + BookContent.NewBookInfo.BOOK_RATING+" TEXT, "
                + BookContent.NewBookInfo.BOOK_SHELF+" TEXT);";


public BookDBHelper(Context context){
    super(context, DATABASE_BOOKS_NAME, null, DATABASE_BOOKS_VERS);
    Log.e("DATABASE OPERATIONS", " DATABASE CREATED");
}

@Override
public void onCreate(SQLiteDatabase bookdb) {

    bookdb.execSQL(CREATE_QUERY_BOOKS);
    Log.e("DATABASE OPERATIONS", " DATABASE CREATED");
}
public void addInformations(byte[] image, String booktitle, String bookauthor, String bookdate, String bookrating, String bookshelf, SQLiteDatabase bookdb)
{

    ContentValues contentValues = new ContentValues();
    contentValues.put(BookContent.NewBookInfo.BOOK_IMAGE, image);
    contentValues.put(BookContent.NewBookInfo.BOOK_TITLE, booktitle);
    contentValues.put(BookContent.NewBookInfo.BOOK_AUTHOR, bookauthor);
    contentValues.put(BookContent.NewBookInfo.BOOK_DATE, bookdate);
    contentValues.put(BookContent.NewBookInfo.BOOK_RATING, bookrating);
    contentValues.put(BookContent.NewBookInfo.BOOK_SHELF, bookshelf);

    bookdb.insert(BookContent.NewBookInfo.TABLE_NAME_BOOKS, null, contentValues);
    Log.e("DATABASE OPERATIONS", "ON ROW INSERTED");
}
public Cursor getInformations(SQLiteDatabase bookdb){
    Cursor cursor2;
        String[] projections = {
                BookContent.NewBookInfo.BOOK_IMAGE,
                BookContent.NewBookInfo.BOOK_TITLE,
                BookContent.NewBookInfo.BOOK_AUTHOR,
                BookContent.NewBookInfo.BOOK_DATE,
                BookContent.NewBookInfo.BOOK_RATING,
                BookContent.NewBookInfo.BOOK_SHELF};
    cursor2 = bookdb.query(BookContent.NewBookInfo.TABLE_NAME_BOOKS, projections,null, null, null, null, null);
    return cursor2;
}

EDITED:

    public void saveBook(View view) { //Click on save Book saving it to SQL Database


    String title = titleText.getText().toString();
    String author = authorText.getText().toString();
    String date = dateText.getText().toString();
    String rating = ratingCountText.getText().toString();
    String shelf = shelfText.getText().toString();

    BitmapDrawable bitmapDrawable = (BitmapDrawable) thumbView.getDrawable();
    Bitmap bitmap = bitmapDrawable.getBitmap();
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
    byte[] blob = stream.toByteArray();

    bookDBHelper = new BookDBHelper(context1);

    sqLiteDatabase1 = bookDBHelper.getWritableDatabase();

    bookDBHelper.addInformations(blob,title, author, date, rating, shelf, sqLiteDatabase1);
    Toast.makeText(getBaseContext(), "Data Saved", Toast.LENGTH_LONG).show();
    bookDBHelper.close();
}

I dont find my error, thats why I am writing to you. Maybe you experts can help me learn something new.

Sorry for the dumb question... I just started programming recently

EDITED

Ok I have a Nullpointer at ´bookimage = BitmapFactory.decodeByteArray(blob,0,blob.length);`

I Dont know why, because I saved an Image and the blob shouldnt be empty.

is there a workaround? How can I can add an If clause or anything else?

Community
  • 1
  • 1
K.Horst
  • 75
  • 9
  • what line is BookDataListActivity 130? – nano_nano Jan 26 '16 at 15:38
  • 1
    Are you sure `byte[] blob` is not null before using it? – George Mulligan Jan 26 '16 at 15:39
  • just look at the line at 130 of `BookDataListActivity` (the line is inside `onCreate` method) and find the error – Jordi Castilla Jan 26 '16 at 15:39
  • The error is almost certainly in this line (though I didn't count to confirm): `bookimage = BitmapFactory.decodeByteArray(blob,0,blob.length);`. The `blob` value you retrieved from the database is `null`. You should catch that case in code and handle it appropriately. You may want *also* to consider whether you should constrain the corresponding DB column to be `NOT NULL`. – John Bollinger Jan 26 '16 at 15:44
  • @JohnBollinger thanks for the advise, I didnt now that the numbers behind the errors is the linenumber. Like a workaround. Do you have a tutorial how I can do this. I started programming 3 weeks ago . – K.Horst Jan 26 '16 at 15:49
  • @GeorgeMulligan actually yes. Because I scanned and saved a book + book image - so the blob shouldn't be empty Edited: Never Mind!! It works. But if there is no Image available it doesnt work. How do I set an option for this? – K.Horst Jan 26 '16 at 16:26
  • @K.Horst I know you THINK it shouldn't be empty but I asked are you SURE. I thought I knew something plenty of times until proven wrong by debugging the code. You should start from the beginning and verify `byte[] blob = stream.toByteArray();` is returning a populated `byte[]` and follow your code from there. – George Mulligan Jan 26 '16 at 16:34
  • @GeorgeMulligan Hi, I figured out the problem: I cleared my hole database. And then I added books with images and started the Listview - worked perfectly. All books were showed in the list. Then I added a book without an image, - the Listview wouldnt start. And gives the Nullpointer So I need a method or something to ignore this kind of situation, when there is an "empty blob" . Do you have a hint for this struggle? – K.Horst Jan 26 '16 at 19:35
  • @K.Horst Nice job finding your problem. One solution would be to have a default image you assign to all books that do not have their own image. That way all books will have an image. You could then also add `NOT NULL` to your BOOK_IMAGE column definition to help make sure you do not accidentally insert a null image. – George Mulligan Jan 26 '16 at 19:52
  • @GeorgeMulligan you mean: `public static final String BOOK_IMAGE = "book_image";`in `public static final String BOOK_IMAGE = "not null"; `? – K.Horst Jan 26 '16 at 20:05
  • It's actually when you are creating the table. `+ BookContent.NewBookInfo.BOOK_IMAGE +" BLOB NOT NULL, "` – George Mulligan Jan 26 '16 at 20:14
  • @GeorgeMulligan unfortunately this does not work :( – K.Horst Jan 26 '16 at 20:35
  • What does not work about it? – George Mulligan Jan 26 '16 at 20:35
  • I get the Nullpointer Error again, when I add a book without an image. I havent implemented the default picture at the moment. – K.Horst Jan 26 '16 at 20:39
  • That really should be working. Either way now that I think about it an even better approach to avoid inserting duplicate images in your database would be to ALLOW null values inserted and to set the default image after checking if the column is null like this: `if(cursor2.isNull(0)) { // get default image} else { //use byte[] from cursor to create image}` – George Mulligan Jan 26 '16 at 20:52
  • @GeorgeMulligan It works with an default Image.! Thanks a lot – K.Horst Jan 27 '16 at 14:34
  • @KHorst You're welcome. I'm happy you got it working. Good job! – George Mulligan Jan 27 '16 at 14:35

0 Answers0