Reputation: 1245
This probably shouldn't be too hard to make but I was wondering what would be the best practice in doing it. I plan to create something like this:
I am not sure how to listen for those changes and process them. I know I can start a service on boot by creating new Broadcats receiver:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, MyService.class);
context.startService(service);
}
}
And defining it inside manifest:
<receiver android:name="MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
And this is simple service:
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;
}
}
}
Service should be running now. How can I now implement periodic check of my database or listen for database changes? What would the recommended design or best practice to implement this process? Any idea is most welcome :)
EDIT
Some extra explanation. User who is using the app is the only one who can update database. It's a local SQLite database which is created inside a class which extends SQLiteOpenHelper. The database is updated when user fills some predefined EditText views inside Activity and clicks on a button to save data. Service needs to process each new row inside that table. Sometimes it can happen the user turns off his device or kills his app before data is processed. In that case service needs to continue processing data after user boots his device again or starts an app.
Upvotes: 1
Views: 2458
Reputation: 38605
If your app is the only one that can modify the database, and only as a result of user action, then you always know exactly the moment your table has been updated. Simply initiate the processing whenever you perform an insert.
If you want that processing done in a service, use an IntentService
. IntentService processes everything on a background thread so you can do operations like network requests, and it automatically stops itself when it has no more work to do.
I don't know how long this processing of yours takes, but I don't think you should be fearful of the app being killed or the device being turned off. If the user closes the app, the system will not kill it immediately; if the OS does need to kill one of your application components to regain memory, it is less likely to kill your IntentService
than, say, the Activities that are no longer being used (and by then you might be done with your processing anyway, so it won't matter). But in general if the OS is not under memory pressure then it will keep app components around as long as possible so that it takes less time if the user switches back to that app.
The only things that would actually kill your app is a device with too much memory pressure or the user is using a task killer app. If that's truly a concern for you (or if your processing takes so long that you think those situations could happen), then you can consider persisting pending processing tasks to disk before you begin processing. When a task finishes, remove it from disk. Then your boot completed receiver only needs to check if there are pending tasks that didn't complete. You can build your own solution, or you can look at something like Path's JobQueue library: https://github.com/path/android-priority-jobqueue
Upvotes: 1
Reputation: 3274
You could make your service a Singleton
and create another BroadcastReceiver
just for database changes:
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
}
}
And your new receiver could look like this
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);
}
}
Then just call sendBroadcast()
when you update your database
Upvotes: 0