Error java.lang.NullPointerException in SQLiteDatabase Android
All the things you have did correctly, but missed one small thing within your onCreate()
of DataHandler.java
.
@Override
public void onCreate(SQLiteDatabase db)
{
try{
//db.execSQL("TABLE_CREATE");
// Here you passing `TABLE_CREATE` string instead of passing `TABLE_CREATE` variable's string. So kindly remove quotes surrounded by 'TABLE_CREATE' and try.
db.execSQL(TABLE_CREATE);
}
catch(SQLException e)
{
e.printStackTrace();
}
}
And change this,
public static final String TABLE_CREATE = "create table mytable (name text not null, email text not null);";
to
public static final String TABLE_CREATE = "create table mytable (name text not null, email text not null)";
DatabaseHandler.close() - Null pointer exception even if checked
I was wondering about the exact same thing (see included code above). It just does not make sense that this is happening.
Android Error when closing the application
I feel the issue is either database instance or any other object became null but you are calling some method using that object. Always check for null before using any methods of any object. see the sample example
example
if(database != null){
database.close();
}
NullPointerException on getReadableDatabase()
As your class which is not an Activity this.getReadableDatabase();
is firing NullPointerException as it is not getting context to open database.
Use context to open database. try with following :
DatabaseHandler dbz = new DatabaseHandler(Activity.this);
public Context context;
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// assigning context Change your constructor
this.context = context;
}
// Open database using context object
SQLiteDatabase db = this.getReadableDatabase();
Intermittent NPE when inserting data into SQLite
As mentioned here SQLiteDatabase close() function causing NullPointerException when multiple threads
The reason for your bug could be that you close the database at some point. Probably concurrently while the task that fails was not finished.
I've followed the stacktrace a bit and this is what roughly happens:
AlbumsData.insertOrIgnore(AlbumsData.java:89)
You callinsertWithOnConflict
, which builds the resulting sql string ("INSERT OR IGNORE INTO..."
) then wraps that together with the values from yourContentValues
into aSQLiteStatement
.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1844)
- The resulting statement is to be executed nowSQLiteStatement.executeInsert(SQLiteStatement.java:112)
- before the actual insert can happen, the database needs to acquire a lock.SQLiteStatement.acquireAndLock(SQLiteStatement.java:247)
- some checks happen here, the database object is as far as I can see not null at that point. Code decides that it has to start a transaction. The database object itself is as far as I can see not locked at that point.SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:605)
- just forwardingSQLiteDatabase.beginTransaction(SQLiteDatabase.java:690)
- after some checks (not sure if database has to exist here) it will try to executeexecSQL("BEGIN IMMEDIATE;")
SQLiteDatabase.execSQL(SQLiteDatabase.java:1965)
- just forwardSQLiteDatabase.executeSql(SQLiteDatabase.java:2025)
- builds anotherSQLiteStatement
out of"BEGIN IMMEDIATE;
. This one should be executed nowSQLiteStatement.executeUpdateDelete(SQLiteStatement.java:96)
- starts with checking the database lock, this seems to be okay and the database should not be null here. The statement is then executed and finally the database is to be unlocked again.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:290)
- cleans up some stuff and in the end fails with NPE because the database isnull
.
Line numbers don't match so there are probably vendor modifications / additions in that code.
As you can see, the code crashes before actually using the data you supplied. It was about to do
BEGIN TRANSACTION IMMEDIATE; -- crash
INSERT INTO table (...) VALUES (...);
-- (end transaction)
That makes it in my opinion a framework bug. The database object that is internally handled there should not be able to be null
somewhere down the line, especially when it seems that it was not null further up in the stack.
I also think that it is possible that another hidden exception could be the root cause for this. There are a lot of try { /* do stuff */ } finally { /* clean up */ }
blocks within the code and the finally
part will be executed even if the try
part throws an exception. Now the finally
block could cause another exception and the result is AFAIK that the original exception is replaced by the new exception from the finally block.
Especially executeUpdateDelete()
is like
try {
acquireAndLock(WRITE);
// actual statement execution
} finally {
releaseAndUnlock();
}
if the database is closed at that point, acquireAndLock
or any code in the try
part could fail and that could leave the database object at null
which causes releaseAndUnlock
to fail again. You should get the same stacktrace.
Apart from that, don't do empty catch blocks like catch (SQLiteException e) { /* empty */ }
. Log them with ACRA if possible / you don't do that already.
sporadic NullPointerException despite the fact, that the Object is not null
Found the solution:
The Problem was that the DbHelper Object was created on the UI thread but closed in the asyncTask worker thread.
After I moved the .close() into the onPostExecute() method the exception disappeared.
private class processCursorTask extends AsyncTask<Integer[], Void, Dataset[]> {
private DbHelper mDb;
processCursorTask(DbHelper db) {
super();
mDb=db;
}
@Override
protected Dataset[] doInBackground(Integer... args) {
Dataset[] res=mDb.getCursorFiltered(args);
return res;
}
protected void onPostExecute(Dataset[] result) {
mDb.close();
setListView(result);
}
}
Android NULL Pointer Exception and Fragment data transmission
Your init()
function is probably try to find views inside fragments in view pager. However, at that moment, the fragments are not inflated yet, so your views in the activity are null and trying to do operation on them gives NPE. You should use onCreateView()
of Fragment classes to find those views. Then you may notify main activity via callback mechanism.
For example, create FirstFragment
as follows:
public class FirstFragment extends Fragment {
private OnFirstFragmentReadyListener callback;
@Override
public void onAttach(Context context) {
super.onAttach(context);
// This makes sure that the container activity has implemented the callback.
try {
callback = (OnFirstFragmentReadyListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnFirstFragmentReadyListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_first, container, false);
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Notify the parent activity that the fragment is inflated.
callback.onFirstFragmentReady();
}
public interface OnFirstFragmentReadyListener {
void onFirstFragmentReady();
}
}
Let the layout of FirstFragment
as follows (referenced above as fragment_first
):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/first_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Assume we created two more similar fragment classes named as SecondFragment
and ThirdFragment
. Then the activity should be like this:
public class MainActivity extends AppCompatActivity implements FirstFragment.OnFirstFragmentReadyListener,
SecondFragment.OnSecondFragmentReadyListener, ThirdFragment.OnThirdFragmentReadyListener {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager =(ViewPager) findViewById(R.id.pager);
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
// Don't call these functions here, spread them into callbacks.
// init();
// Action();
}
@Override
public void onFirstFragmentReady() {
TextView firstTextView = (TextView) findViewById(R.id.first_label);
...
// Now you have the views from FirstFragment instance.
// You can now call setText() or setOnClickListener() here.
}
@Override
public void onSecondFragmentReady() {
TextView secondTextView = (TextView) findViewById(R.id.second_label);
...
// Now you have the views from SecondFragment instance.
// You can now call setText() or setOnClickListener() here.
}
@Override
public void onThirdFragmentReady() {
TextView thirdTextView = (TextView) findViewById(R.id.third_label);
...
// Now you have the views from ThirdFragment instance.
// You can now call setText() or setOnClickListener() here.
}
}
Although this code works, this may not be the best way. I think it is better to do operations on views like setting texts or assigning OnClickListeners in fragments itself. If you need to notify a fragment after an action happened in the parent activity, you can implement public methods inside fragments and you can call them from the parent activity when needed.
Related Topics
What Is More Efficient? Static, Data Passing, Shared Preferences, Database...
Partial Invalidation in Custom Android View with Hardware Acceleration
Why Does Flag_Activity_Clear_Top Not Work
Picture Taken with Camera Intent Is Low Quality on Imageview (7.0+)
Getting Net::Err_Unknown_Url_Scheme While Calling Telephone Number from HTML Page in Android
Firebase Endat() Not Working with Date String
Failed to Resolve: Recyclerview-V7
Android Approach for "Rate My Application"
Disable Android Browser's Input Overlays
Cordova Cannot Add Android Failed with Exit Code Enoent
Android Studio on a Hardware That Does Not Support Virtualization Technology
How to Handle Empty Response Body with Retrofit 2
Is There a Faster Way to Decode HTML Characters to a String Than HTML.Fromhtml()
What Is The Easiest Way to Use Svg Images in Android
How to Update Google Play Services for Android Studio 2.2 Emulators