I m actually developping an Android application with data storage, and I proceed like this :
Activity -> Business services -> Repo (with Spring REST fw). Using this, I m forced to let the activity finish his storing job before closing it (thread treatment, progress dialog ...).
Is this a bad way of coding to use an android service to store data ?
With this, users can continue to navigate, and have the impression to work with a very fluid application. Is this a good solution ?
Thanks
There is no need to keep your activity in the foreground waiting for a background logic to complete.
What you should do instead is to execute this background logic in a way which is 'detached' from your activity.
There are two ways of solving this problem: risky and safe.
The Risky Way
class MyActivity extends Activity {
void calledWhenActivityNeedsToBeClosed() {
// start a thread to do background work
new Thread() {
public void run() {
perform long running logic here
}
}.start();
// and clos the activity without waiting for the thread to complete
this.finish();
}
}
You can use an AsyncTask or any of the java.concurrent constructs instead of the thread. They will all do the work.
I have used this way for years. It mostly works fine. But.. it is inherently flawed.
Why? Because once activity is finish()-ed, Android can at any time reclaim it together with all its resources and including halting of all worker threads.
If your long running work does not exceed several seconds, and I assume your repo update is such, the risk here
is minimal. But why take it?
The Safe Way
Declare a Service and before activity going down activate it to perform the long running action:
class MyActivity extends Activity {
void calledWhenActivityNeedsToBeClosed() {
// delegate long running work to service
startService(this, new Intent(this, MyWorkerService.class));
// and close the activity without waiting for the thread to complete
this.finish();
}
}
This is much safer. Android can, and often does, also kill running services, but is does so much more reluctantly than killing background activities.
Note that if you can see a scenario in which your UI is visible while the worker service is still running, you would probably want to use an IntentService instead.
Finally - if you want to be absolutely assured that background logic will not be cleared by Android, you
should use a foreground service. Below is how to do it, but please be warned - in cases like you have described, a foreground service is probably over engineering:
static final int NOTIF_ID = 100;
// Create the FG service intent
Intent intent = new Intent(getApplicationContext(), MyActivity.class); // set notification activity
showTaskIntent.setAction(Intent.ACTION_MAIN);
showTaskIntent.addCategory(Intent.CATEGORY_LAUNCHER);
showTaskIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pIntent = PendingIntent.getActivity(
getApplicationContext(),
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notif = new Notification.Builder(getApplicationContext())
.setContentTitle(getString(R.string.app_name))
.setContentText(contentText)
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(pIntent)
.build();
startForeground(NOTIF_ID, notif);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With