Reputation: 23
iem following a tutorial on youtube about using SQLite in android and the code crashes the app on start code
MainActivity.java
package com.example.asd;
import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity {
VivzHelper vivzHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vivzHelper = new VivzHelper(this);
SQLiteDatabase sqLiteDatabase = vivzHelper.getWritableDatabase();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Message.java
package com.example.asd;
import android.content.Context;
import android.widget.Toast;
public class Message {
public static void message(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
VivzHelper.java
package com.example.asd;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class VivzHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "vivzdatabase";
private static final String TABLE_NAME = "VIVZTABLE";
private static final int DATABASE_VERSION = 1;
private static final String UID = "_id";
private static final String NAME = "Name";
private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + UID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + NAME + " VARCHAR(255));";
private static final String DROP_TABLE = "DROP TABLE IF EXISTS" + TABLE_NAME;
private Context context;
public VivzHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Message.message(context, "constructor called");
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(CREATE_TABLE);
Message.message(context, "onCreate called");
} catch (SQLException e) {
Message.message(context, "" + e);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Message.message(context, "onUpgrade called");
db.execSQL(DROP_TABLE);
onCreate(db);
} catch (SQLException e) {
Message.message(context, "" + e);
}
}
}
The app crashes on
SQLiteDatabase sqLiteDatabase = vivzHelper.getWritableDatabase();
error log
12-11 19:49:16.459: E/AndroidRuntime(6043): FATAL EXCEPTION: main
12-11 19:49:16.459: E/AndroidRuntime(6043): Process: com.example.asd, PID: 6043
12-11 19:49:16.459: E/AndroidRuntime(6043): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.asd/com.example.asd.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2695)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2769)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.app.ActivityThread.access$900(ActivityThread.java:177)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.os.Handler.dispatchMessage(Handler.java:102)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.os.Looper.loop(Looper.java:135)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.app.ActivityThread.main(ActivityThread.java:5910)
12-11 19:49:16.459: E/AndroidRuntime(6043): at java.lang.reflect.Method.invoke(Native Method)
12-11 19:49:16.459: E/AndroidRuntime(6043): at java.lang.reflect.Method.invoke(Method.java:372)
12-11 19:49:16.459: E/AndroidRuntime(6043): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
12-11 19:49:16.459: E/AndroidRuntime(6043): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
12-11 19:49:16.459: E/AndroidRuntime(6043): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.widget.Toast.<init>(Toast.java:130)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.widget.Toast.makeText(Toast.java:427)
12-11 19:49:16.459: E/AndroidRuntime(6043): at com.example.asd.Message.message(Message.java:9)
12-11 19:49:16.459: E/AndroidRuntime(6043): at com.example.asd.VivzHelper.onCreate(VivzHelper.java:29)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
12-11 19:49:16.459: E/AndroidRuntime(6043): at com.example.asd.MainActivity.onCreate(MainActivity.java:18)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.app.Activity.performCreate(Activity.java:6178)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
12-11 19:49:16.459: E/AndroidRuntime(6043): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2648)
12-11 19:49:16.459: E/AndroidRuntime(6043): ... 10 more
I do not know whats wrong with the code it looks exactly the same as in video ???
Upvotes: 2
Views: 203
Reputation: 44571
What is the problem?
getWritableDatabase calls your onCreate()
The first time this is called, the database will be opened and onCreate(SQLiteDatabase), onUpgrade(SQLiteDatabase, int, int) and/or onOpen(SQLiteDatabase) will be called.
in onCreate()
you have
Message.message(context, "onCreate called");
context
, at this point, is null
because it is declared as a member variable at the top as
private Context context;
but it is never initialized. You pass the Context
from your Activity
to the db helper class constructor. Initializing the member variable, context
, there gives that variable a value when you pass it to your message()
function, hence getting rid of the NPE
.
How did we get here?
Your stacktrace shows
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'android.content.res.Resources android.content.Context.getResources()'
on a null object reference
So you are trying to use a Context
object to "do something" which, in this case, is to create and show a Toast
object. Because if we look just a little further up in the stacktrace to the first line which references your project we find
at com.example.asd.Message.message(Message.java:9)
which is this line
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
what could cause a problem here with the given stacktrace? Yes, context
being null
.
Which takes us back to
The app crashes on
SQLiteDatabase sqLiteDatabase = vivzHelper.getWritableDatabase();
as you stated in your post. It crashes there, not because something in that line is explicitly wrong, but because something in that line calls something else that is crying for help.
Upvotes: 1