Evgeniy Mishustin
Evgeniy Mishustin

Reputation: 3794

Service writing to a database and activity reads from it

Architecture help needed. I'm building an app which will consist from Service and Activity. Service will write data to SQLite DB and Activity should read it and display. There are two problems: 1) Activity should receive updates on-the-fly. 2) If Activity goes background it should load all the changes when it returns foreground.

After two days of research I assume that the only way to implement it is creating ContentProvider as the middle layer and using CursorLoader in Activity. Am I right? Any other suggestions? Any help would be appreciated. Thank you.

Upvotes: 0

Views: 54

Answers (1)

dev.bmax
dev.bmax

Reputation: 10591

Another way is making your own observer pattern implementation. Here is my version:

The observer

/**
 * Receives notification of updates on database contents.
 */
public interface DatabaseObserver {
    /**
     * This method is called if the observable database's notifyObservers 
     * method is called (because the observable database has been updated.
     */
    void onUpdate(String tableName);
}

The observable

/**
 * Used to notify a group of Observer objects when a change occurs.
 */
public interface ObservableDatabase {
    /**
     * Adds the specified observer to the list of observers.
     */
    void addObserver(DatabaseObserver observer);

    /**
     * Removes the specified observer from the list of observers.
     */
    void removeObserver(DatabaseObserver observer);
}

The database helper

public class DatabaseHelper extends SQLiteOpenHelper implements ObservableDatabase {
    private static DatabaseHelper sInstance;

    private CopyOnWriteArrayList<DatabaseObserver> mObservers = new CopyOnWriteArrayList<>();

    /**
     * Returns the single instance of Database helper
     */
    public static synchronized DatabaseHelper getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new DatabaseHelper(context.getApplicationContext());
        }

        return sInstance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_STATEMENT);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(DROP_STATEMENT);
        onCreate(db);
    }

    /**
     * Adds the specified observer to the list of observers.
     */
    public void addObserver(DatabaseObserver observer) {
        mObservers.addIfAbsent(observer);
    }

    /**
     * Removes the specified observer from the list of observers.
     */
    public void removeObserver(DatabaseObserver observer) {
        mObservers.remove(observer);
    }

    private DatabaseHelper(Context context) {
        super(context, DB_NAME, null, BuildConfig.VERSION_CODE);
    }

    private void notifyObservers(String tableName) {
        for (DatabaseObserver observer: mObservers) {
            observer.onUpdate(tableName);
        }
    }
}

Note, that each writing method in your database helper should call notifyObservers(tableName) after modifying the database.

Now, any component can subscribe to this database helper to be updated. And make sure that the activity is not dead in the onUpdate callback before you try to update the UI.

Upvotes: 1

Related Questions