侦听数据库更改的服务

时间:2015-01-12 15:50:04

标签: android android-service android-broadcast

这可能不应该太难,但我想知道这样做的最佳做法是什么。我打算创建这样的东西:

  • 服务需要一直运行。它还需要在用户启动设备时启动。
  • 服务正在处理来自数据库的数据,因此需要监听一个表的数据库更改。
  • 用户执行操作以将新行插入数据库后,服务应注册该行并开始处理数据。

我不确定如何倾听这些变化并处理它们。我知道我可以通过创建新的Broadcats接收器来启动服务:

public class MyReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    Intent service = new Intent(context, MyService.class);
    context.startService(service);
  }
}

在清单中定义它:

<receiver android:name="MyReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
</receiver>

这是一项简单的服务:

public class MyService extends Service {
  private final IBinder mBinder = new MyBinder();
  private ArrayList<String> list = new ArrayList<String>();

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    // Should check for database change here?

    // fetches data from database
    List<String> data = Manager.get(context).getData();

    return Service.START_NOT_STICKY;
  }

  @Override
  public IBinder onBind(Intent arg0) {
    return mBinder;
  }

  public class MyBinder extends Binder {
    MyService getService() {
      return MyService.this;
    }
  }

}

服务现在应该正在运行。我现在如何定期检查数据库或监听数据库更改?实施此流程的推荐设计或最佳实践是什么?任何想法都是最受欢迎的:)

修改

一些额外的解释。使用该应用程序的用户是唯一可以更新数据库的用户。它是一个本地SQLite数据库,它在一个扩展SQLiteOpenHelper的类中创建。当用户在Activity中填充一些预定义的EditText视图并单击按钮以保存数据时,数据库会更新。服务需要处理该表中的每个新行。有时,在处理数据之前,用户可能会关闭他的设备或杀死他的应用程序。在这种情况下,服务需要在用户再次启动设备或启动应用程序后继续处理数据。

2 个答案:

答案 0 :(得分:1)

如果您的应用程序是唯一可以修改数据库的应用程序,并且仅作为用户操作的结果,那么您始终可以确切知道表的更新时刻。只需执行插入操作即可启动处理。

如果您希望在服务中完成该处理,请使用IntentService。 IntentService处理后台线程上的所有内容,以便您可以执行网络请求等操作,并且在没有其他工作要做的时候会自动停止。

我不知道你的处理需要多长时间,但我不认为你应该害怕应用程序被杀或设备被关闭。如果用户关闭应用程序,系统不会立即将其终止;如果操作系统 需要杀死你的一个应用程序组件以重新获得内存,那么杀死你的IntentService的可能性就会低于不再使用的活动(以及那么你可能已经完成了你的处理,所以它不重要)。但一般情况下,如果操作系统没有内存压力,那么它会尽可能长时间保持应用程序组件,以便用户切换回该应用程序所需的时间更短。

实际上会杀死你的应用程序的唯一因素是具有太大内存压力的设备或者用户正在使用任务杀手应用程序。如果您真的担心这一点(或者如果您的处理时间过长而您认为可能会发生这种情况),那么您可以考虑在开始处理之前将待处理的处理任务保留到磁盘。任务完成后,将其从磁盘中删除。然后你的启动完成接收器只需要检查是否有未完成的待处理任务。您可以构建自己的解决方案,也可以查看Path的JobQueue库:https://github.com/path/android-priority-jobqueue

答案 1 :(得分:0)

您可以将服务设为Singleton并仅为数据库更改创建另一个BroadcastReceiver

public class YourService extends Service{

 private static YourService sInstance;
 public static YourService getInstance(){ return sInstance; } 
 onCreate(){
  sInstance = this; 
  ...
  }

 public void processSomeData(YourData data){
   //do the stuff you wanna do
    }
}

你的新接收器看起来像这样

public class DBChangeReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
  YourData data;
  //grab your data from the intent
  YourService.getInstance().processSomeData(data);
  }
}

然后在更新数据库时调用sendBroadcast()