Service & Alarm BroadcastReceiver



Services execute long-running operations in the background that does not provide a user interface.
  • startService(): Started service continues to run in the background indefinitely, even if the application that starts it is switched or destroyed! Therefore such a service should stop itself when the designated operation is finished.
  • bindService(): Bound provides client-server / interprocess communication. The service is destroyed when the last component unbinds it.
A service by default runs in the main thread of its hosting process; so a background thread/AsyncTask must be used for long running tasks in a service. Use intent service class (a queue of intents handled in background thread).
 

Service Life cycle

  onCreate
    onStartCommand          init background task, startForeground
      onDestroy
 
 
        Service Framework
            /      \
IntentService      SyncAdapter
 

IntentService

IntentService creates default worker thread, provides a default implementation of onStartCommand() that sends intents to a work queue, and then to your onHandleIntent() implementation. It stops the service after all start requests have been handled.
 
    Intent intent = new Intent(getActivity(), SunshineService.class);
    intent.putExtra(SunshineService.LOCATION_KEY, location);
    getActivity().startService(intent);
 
    public class SunshineService extends IntentService {
 
        protected void onHandleIntent(Intent intent) {
            getContentResolver().bulkInsert(WeatherContract.WeatherEntry.CONTENT_URI, cvArray);
        }
    }

Service with Alarm: IntentService + Alarm BroadcastReceiver

<service android:name=".service.SunshineService"/>
    <receiver android:name=".service.SunshineService$AlarmReceiver" android:enabled="true"/>
 
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent alarmIntent = new Intent(context, SunshineService.AlarmReceiver.class);
    alarmIntent.putExtra(SunshineService.LOCATION_KEY, location);
    // Wrap it in a pending intent which only fires once.
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_ONE_SHOT); //getBroadcast(context, 0, i, 0);
    // Either: Set the AlarmManager to wake up the system based on locale clock.
    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pendingIntent);
    // Or: Set the AlarmManager to wake up the system based on elapsed time (better approach)
    alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5000, pendingIntent);
 
 
    // Add BroadcastReceiver to receive the alarm
    public class SunshineService extends IntentService {
        static public class AlarmReceiver extends BroadcastReceiver {
            public void onReceive(Context context, Intent intent) {
                // Forward it to service handler
                Intent sendIntent = new Intent(context, SunshineService.class);
                sendIntent.putExtra(SunshineService.LOCATION_KEY, intent.getStringExtra(SunshineService.LOCATION_KEY));
                context.startService(sendIntent);
            }
        }
        protected void onHandleIntent(Intent intent) {
            getContentResolver().bulkInsert(WeatherContract.WeatherEntry.CONTENT_URI, cvArray);
        }
    }



No comments:

Post a Comment