0

I'm trying to get started on creating my first real practice app on android and I've run into a bit of trouble. It's an app that will contain "ideas" in a sort of to do list style format. I finished making the activity where it will be displayed and the activity that will add the idea but upon clicking the button the application stops working. After debugging it I found out that the reason is in the onClick method, specifically the portion that is:

06-26 22:44:26.590    1136-1136/com.ivywire.ideastem           E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.NullPointerException
        at com.ivywire.ideastem.IdeasDbAdapter.createIdea(IdeasDbAdapter.java:78)
        at com.ivywire.ideastem.IdeaAddActivity$1.onClick(IdeaAddActivity.java:44)
        at android.view.View.performClick(View.java:4204)
        at android.view.View$PerformClick.run(View.java:17355)
        at android.os.Handler.handleCallback(Handler.java:725)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5041)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
        at dalvik.system.NativeStart.main(Native Method)

So I tried taking out some parts

Idea idea = new Idea(name, summary);
databaseHandler.createIdea(idea);

when taken out it works. This is the full activity code.

import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.view.View.OnClickListener;


public class IdeaAddActivity extends Activity {
    IdeasDbAdapter databaseHandler;

    private EditText ideaName;
    private EditText ideaSummary;
    private Button addButton;

    String name;
    String summary;

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

        ideaName = (EditText) findViewById(R.id.ideaName);
        ideaSummary = (EditText) findViewById(R.id.ideaSummary);
        addButton = (Button) findViewById(R.id.addIdeaButton);

        name = ideaName.getText().toString();
        summary = ideaSummary.getText().toString();

        databaseHandler = new IdeasDbAdapter(this);

        addButton.setOnClickListener(addListener);
    }

    private OnClickListener addListener = new OnClickListener(){
        public void onClick(View view){
            Idea idea = new Idea(name, summary);
            databaseHandler.createIdea(idea);
            sendToMain(view);
        }
    };

    public void sendToMain(View view){
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.idea_add, menu);
        return true;
    }

}

This is the IdeasDbAdapter class:

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

public class IdeasDbAdapter {

    public static final String KEY_ROWID = "_id";
    public static final String KEY_NAME = "name";
    public static final String KEY_SUMMARY = "summary";

    private static final String TAG = "IdeasDbAdapter";
    private DatabaseHelper mDbHelper;
    private SQLiteDatabase mDb;

    private static final String DATABASE_NAME = "Brainstorm";
    private static final String SQLITE_TABLE = "Ideas";
    private static final int DATABASE_VERSION = 1;

    private final Context mCtx;

    private static final String DATABASE_CREATE =
            "CREATE TABLE if not exists " + SQLITE_TABLE + " (" +
                    KEY_ROWID + " integer PRIMARY KEY autoincrement," +
                    KEY_NAME + "," +
                    KEY_SUMMARY + ");";

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }


        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.w(TAG, DATABASE_CREATE);
            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS " + SQLITE_TABLE);
            onCreate(db);
        }
    }

    public IdeasDbAdapter(Context ctx) {
        this.mCtx = ctx;
    }

    public IdeasDbAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

    public void close() {
        if (mDbHelper != null) {
            mDbHelper.close();
        }
    }

    public long createIdea(Idea idea) {
        String name = idea.getName();
        String summary = idea.getSummary();
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_NAME, name);
        initialValues.put(KEY_SUMMARY, summary);

        return mDb.insert(SQLITE_TABLE, null, initialValues);
    }

    public boolean deleteAllIdeas() {

        int doneDelete = 0;
        doneDelete = mDb.delete(SQLITE_TABLE, null , null);
        Log.w(TAG, Integer.toString(doneDelete));
        return doneDelete > 0;

    }

    public Cursor fetchIdeasByName(String inputText) throws SQLException {
        Log.w(TAG, inputText);
        Cursor mCursor = null;
        if (inputText == null  ||  inputText.length () == 0)  {
            mCursor = mDb.query(SQLITE_TABLE, new String[] {KEY_ROWID,
                    KEY_NAME, KEY_SUMMARY},
                    null, null, null, null, null);

        }
        else {
            mCursor = mDb.query(true, SQLITE_TABLE, new String[] {KEY_ROWID,
                    KEY_NAME, KEY_SUMMARY},
                    KEY_NAME + " like '%" + inputText + "%'", null,
                    null, null, null, null);
        }
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;

    }

    public Cursor fetchAllIdeas() {

        Cursor mCursor = mDb.query(SQLITE_TABLE, new String[] {KEY_ROWID,
                KEY_NAME, KEY_SUMMARY},
                null, null, null, null, null);

        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;
    }
}

Line 78 that was referred in the nullpointer exception was

return mDb.insert(SQLITE_TABLE, null, initialValues);

If anybody could give me tips since I'm fairly confused and searching as best as I can, I'd appreciate it.

user2525981
  • 159
  • 1
  • 3
  • 10
  • Did you debug? I guess the mDb is null. When do you create the instance? – jpardogo Jun 26 '13 at 22:56
  • You need to call open() in IdeasDbAdapter to create the instance. I would do singelton for this. – jpardogo Jun 26 '13 at 23:00
  • do you mean something like this? public void onClick(View view){ Idea idea = new Idea(name, summary); databaseHandler.open(); databaseHandler.createIdea(idea); sendToMain(view); databaseHandler.close(); } – user2525981 Jun 26 '13 at 23:09
  • I miswrote the above. I meant using databaseHandler.open() in onCreate and databaseHandler.close() right after sending the app to another activity. – user2525981 Jun 26 '13 at 23:13
  • I look for a tutorial that explain everything nicely. Although I think the problem is that you didn´t initialise mDB and it is still null when you try to use it, it is better you make sure you use the best practices on your architecture. – jpardogo Jun 26 '13 at 23:31

2 Answers2

0

I dont Know the string on your others code but look at my code and see what you have to do

addactivity:

 saveBtn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {

           memo = new Memo();
            memo.setHeadLine(headLineTxt.getText().toString());
            memo.setFullMemo(fullMemoTxt.getText().toString());
                              memo = datasource.createMemo(memo);
                  finish();
        }
    });

IdeasDbAdapter:

public  Memo createMemo(Memo memo) {
    //Used to store data like : COLUMN_NAME , VALUE.
    ContentValues values = new ContentValues();
    values.put(COLUMN_HEAD_LINE, memo.getHeadLine());
    values.put(COLUMN_FULL_MEMO, memo.getFullMemo());
    //Insert new memo and get the id of it.
    long insertId = database.insert(TABLE_NAME, null,
            values);

I Hope it help you.

User_1191
  • 981
  • 2
  • 8
  • 24
H4F
  • 131
  • 10
  • sorry, this didn't work. The extra bracket gives a syntax error and after taking it out I still get the same error. – user2525981 Jun 26 '13 at 23:32
-1

I was looking for a nice tutorial that explain how to create a good SQLite Database and Content providers for it. I found this one and I think that if you follow it, you will have a good architecture and no problems accessing, deleting or upgrading your data:

http://www.vogella.com/articles/AndroidSQLite/article.html#todo

jpardogo
  • 5,636
  • 2
  • 23
  • 27
  • I've heard that Content Providers are used mostly for databases that are sharing data between applications. Are they efficient for stuff that don't really need that too? – user2525981 Jun 26 '13 at 23:33
  • Documentation says ... "You don't need to develop your own provider if you don't intend to share your data with other applications. However, you do need your own provider to provide custom search suggestions in your own application. You also need your own provider if you want to copy and paste complex data or files from your application to other applications." But I think they are really useful and make all cleaner. – jpardogo Jun 26 '13 at 23:39
  • Look at this answer and its commentaries ... http://stackoverflow.com/questions/4936712/when-to-use-a-content-provider ... I think it worth the effort to build a Content provider. And this library the speak about... looks good....https://github.com/casidiablo/persistence – jpardogo Jun 26 '13 at 23:56
  • to content providers or the library XD – jpardogo Jun 27 '13 at 00:06