Inserts, updates, deletes and reads are generally OK from multiple threads, but Brad's answer is not correct. You have to be careful with how you create your connections and use them. There are situations where your update calls will fail, even if your database doesn't get corrupted.
The basic answer.
The SqliteOpenHelper object holds on to one database connection. It appears to offer you a read and write connection, but it really doesn't. Call the read-only, and you'll get the write database connection regardless.
So, one helper instance, one db connection. Even if you use it from multiple threads, one connection at a time. The SqliteDatabase object uses java locks to keep access serialized. So, if 100 threads have one db instance, calls to the actual on-disk database are serialized.
So, one helper, one db connection, which is serialized in java code. One thread, 1000 threads, if you use one helper instance shared between them, all of your db access code is serial. And life is good (ish).
If you try to write to the database from actual distinct connections at the same time, one will fail. It will not wait till the first is done and then write. It will simply not write your change. Worse, if you don’t call the right version of insert/update on the SQLiteDatabase, you won’t get an exception. You’ll just get a message in your LogCat, and that will be it.
So, multiple threads? Use one helper. Period. If you KNOW only one thread will be writing, you MAY be able to use multiple connections, and your reads will be faster, but buyer beware. I haven't tested that much.
Here's a blog post with far more detail and an example app.
Gray and I are actually wrapping up an ORM tool, based off of his Ormlite, that works natively with Android database implementations, and follows the safe creation/calling structure I describe in the blog post. That should be out very soon. Take a look.
In the meantime, there is a follow up blog post:
Also checkout the fork by 2point0 of the previously mentioned locking example:
I was having this problem too, until I realized that I had specified the wrong layout in setContentView()
of the onCreate()
method of the FragmentActivity.
The id passed into FragmentTransaction.add()
, in your case R.id.feedContentContainer
, must be a child of the layout specified in setContentView()
.
You didn't show us your onCreate()
method, so perhaps this is the same problem.
Best Answer
If Android decides to recreate your Fragment later, it's going to call the no-argument constructor of your fragment. So overloading the constructor is not a solution.
With that being said, the way to pass stuff to your Fragment so that they are available after a Fragment is recreated by Android is to pass a bundle to the
setArguments
method.So, for example, if we wanted to pass an integer to the fragment we would use something like:
And later in the Fragment
onCreate()
you can access that integer by using:This Bundle will be available even if the Fragment is somehow recreated by Android.
Also note:
setArguments
can only be called before the Fragment is attached to the Activity.This approach is also documented in the android developer reference: https://developer.android.com/reference/android/app/Fragment.html