【问题标题】:Service writing to a database and activity reads from it服务写入数据库并从中读取活动
【发布时间】:2016-05-03 13:39:29
【问题描述】:

需要架构帮助。我正在构建一个由ServiceActivity 组成的应用程序。 Service 将数据写入SQLite DB,Activity 应该读取并显示。有两个问题:1)Activity 应该即时接收更新。 2) 如果Activity 进入后台,它应该在返回前台时加载所有更改。

经过两天的研究,我认为实现它的唯一方法是创建ContentProvider 作为中间层并在活动中使用CursorLoader。我对吗?还有其他建议吗?任何帮助,将不胜感激。谢谢。

【问题讨论】:

    标签: android sqlite android-contentprovider loader


    【解决方案1】:

    另一种方法是制作自己的观察者模式实现。这是我的版本:

    观察者

    /**
     * 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);
    }
    

    可观察的

    /**
     * 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);
    }
    

    数据库助手

    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);
            }
        }
    }
    

    注意,数据库助手中的每个写入方法都应该在修改数据库后调用 notifyObservers(tableName)。

    现在,任何组件都可以订阅此数据库助手进行更新。在尝试更新 UI 之前,请确保活动在 onUpdate 回调中没有死。

    【讨论】:

    • 触发 onUpdate() 时应该调用什么方法?我应该扔掉以前的 Loader 并重新启动一个新的吗?
    • 如果您使用的是加载程序,我建议在检查修改后的表是否对您感兴趣后,让加载程序成为 onStartLoading() 和 onUpdate 回调中的观察者,您只需调用 onContentChanged()
    • 我还建议扩展 AsyncTaskLoader。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    相关资源
    最近更新 更多