Android: Access database from activity or fragment?

时间:2015-07-31 19:52:05

标签: android sqlite android-fragments android-intent

I have a MainActivity with three separate fragments. I need to access data from my SQLite database in each of these fragments.

The data object MyObject contains primitive types along with a list of OtherObject objects.

So lets say we have three fragments, FragmentA, FragmentB and FragmentC.

FragmentB creates MyObject objects and saves them into the database. Upon saving, FragmentC is opened and populated with the MyObject data.

FragmentA lists all MyObject objects and upon clicking on an item from the list, will open FragmentC populated with the chosen MyObject.

What is the correct implementation?

Should the activity control all the database access and pass MyObject to the corresponding fragment?

Should each fragment access the database each time to access the data for itself?

Should FragmentA and FragmentB read in the data and pass the corresponding MyObject to FragmentC?

For the case of passing data from fragment -> activity -> fragment or activity -> fragment, which method would fit best:

  1. Parcelable
  2. Intent
  3. Interface (via the activity)

The use of parcelable seems difficult as MyObject contains a list of OtherObject, and all the data can't be decomposed and transferred in an Intent very easily.

This link shows the use of an Interface to transfer data from the fragment to the activity, with the Fragment declaring the interface which is implemented in the activity. To transfer the objects from the activity to the fragment, do you declare another interface in the activity and implement it in the fragment?

I haven't been able to find any straight forward advice.

Thanks for any help

2 个答案:

答案 0 :(得分:2)

1 . implement ContentProvider

A content provider manages access to a central repository of data. A provider is part of an Android application, which often provides its own UI for working with the data.

2 . use ContentResolver

This class provides applications access to the content model.

  • eg. query straight for cursor:
Cursor cursor = getContentResolver().query(...);

A class that performs asynchronous loading of data. While Loaders are active they should monitor the source of their data and deliver new results when the contents change. See LoaderManager for more detail.

why?

  • u separate data model from app logic - in small project it is not advisable but when yr project grows up u will see that effort has paid off.

答案 1 :(得分:1)

If I've interpreted your situation correctly, I would either use interfaces to pass the MyObject object from Fragment B to the Activity, then on to Fragment C, or LocalBroadcastManager or EventBus. Before I get started however, I should point out that I am typing from memory, so I can't give an example for LocalBroadcastManager or GreenRobot's EventBus, but both these options are viable alternatives.

public class FragmentB {
    FragCallbacks mCallbacks;

public interface FragCallbacks {
    void objectSavedToDatabase(MyObject object);
}

@Override
public void onAttach (Activity activity) {
    if (activity instanceof FragCallbacks) {
         mCallbacks = (FragCallbacks) activity;
    }

// Logic for writing to your database, and then, on completion...
mCallbacks.objectSavedToDatabase(objectJustWrittenToDatabase);

Then, in your Activity

public class MainActivity implements FragmentB.FragCallbacks {

FragmentC fragmentC;

@Override
public void objectSavedToDatabase(MyObject object) {
    fragmentC = FragmentC.newInstance(params);
    //If MyObject is Parcelable, you can pass it as a parameter here.
    //This is probably the preferable option. Otherwise, you can use a 
    // "setMyObject()" method.
    getFragmentManager()
        .beginTransaction()
        .replace(...)
        .commit();
   fragmentC.setMyObject(object);