Service in Android

Learn Guo Lin's First Line Code, record your own learning notes, and summarize Service.

Inheritance of service classes and rewriting of service methods

When we want to customize the Service, we must inherit the Service class, rewrite the Service method, and most importantly register the Service where the four components are registered.

<service android:name=".MyService">
</service>

The following are rewritable methods for services:

          

    //The binding service triggers the method, and the return value is passed into the onService Connected parameter of the active ServiceConnection class.
	//The activity calls bindService() and calls back the onBind() method to return an IBinder instance to
	//In the input parameter of onService Connected of the active anonymous class Service Connection
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	//Creating service invocation methods
	public void onCreate() {
		super.onCreate();
	}
	//Start the service invocation method
	public int onStartCommend(Intent intent,int flags,int startId) {
		return super.onStartCommand(intent, flags, startId);
	}
	//Destruction service invocation method
	public void onDestroy() {
		super.onDestroy();
	}

II. Start-up and Stop of Services

Starting and stopping services are similar to displaying startup activities. Services to be started are specified by Intent, and services to be started and stopped by startService(Intent) and startService(Intent). Services can also terminate services by stopSelf() itself.

		//Start the service MyService in the activity
		Intent startIntent=new Intent(this,MyService.class);
		startService(startIntent);
		
		//Stop serving MyService during the activity
		Intent stopIntent=new Intent(this,MyService.class);
		stopService(stopIntent);

3. Binding and unbinding of services, operation of services by activities (communication between activities and services)

The binding of services can make the communication between services and activities more flexible. After we started the service, the service ran the code that played onCreate() and onStartCommend(), and then it ran there, unable to do anything else. But if you use a binding service, the activity can manipulate the running service anytime and anywhere after starting the service (get the Binder instance) so that the service can do more for us (call the method in Binder). (Note: Any service is common in applications, and services can be bound to any activity)

1. Customize a class inherited from Binder in the custom service class, and customize the method of the class (that is, the method provided by the service to the activity), and rewrite onBind() to return the instance object of the custom Binder class.

	//Custom internal classes inherit from Binder, customize start download method and progress method
	private DownloadBinder downloadTask=new DownloadBinder();
	class DownloadBinder extends Binder{
		//Let the service start downloading
		public void startDownload() {
			Log.d("MyService", "startDownload executed");
		}
		//Get the service back on schedule
		public int getProgress() {
			Log.d("MyService", "getProgress executed");
			return 0;
		}
	}
	//The binding service triggers the method, and the return value is passed into the onService Connected parameter of the active ServiceConnection class.
	//The activity calls bindService() and calls back the onBind() method to return an IBinder instance to
	//In the input parameter of onService Connected of the active anonymous class Service Connection
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return downloadTask;
	}

2. Define the anonymous class ServiceConnection in the active class, and override the onService Disconnected (), onService Connected () methods to get the returned custom Binder class instance. At the same time, call the bindService(), unbindService() to bind and unbind the service.

	private MyService.DownloadBinder downloadBinder;
	//ServiceConnection class: Define anonymous classes to bind, unbind services to override invocation methods
	private ServiceConnection connection=new ServiceConnection() {
		//Called when the activity unbundles the service
		public void onServiceDisconnected(ComponentName name) {
			
		}
		//Invoke when activity binds service (parameter IBinder is IBinder returned from onBind() in Service)
		public void onServiceConnected(ComponentName name,IBinder services) {
			//A custom Binder class that obtains services in an activity can call methods in Binder to direct services
			downloadBinder=(MyService.DownloadBinder)services;
			//Let the service start downloading tasks
			downloadBinder.startDownload();
			//Task download progress for service acquisition
			downloadBinder.getProgress();
		}
	};
	//Binding service, connection for custom Service Connection
	Intent bindIntent=new Intent(this,MyService.class);
	bindService(bindIntent,connection,BIND_AUTO_CREATE);
	
	//Unbundling service, connection for custom Service Connection
	unbindService(connection);

Fourth, two ways to start services running in sub-threads

Service runs in the main thread by default. When we deal with some time-consuming tasks (such as download tasks, etc.) running in the background, it may cause ANR situation. To avoid this situation, we need to let time-consuming tasks execute in the sub-thread. Generally, the following two methods are often used:

1. Open subthreads in onStartCommend() and eventually stop the service automatically

public int onStartCommand(Intent intent,int flags,int startId) {
	//Open a sub-thread to execute specific background service code
	new Thread(new Runnable() {
		@Override
		public void run() {
			Log.d("LongRunningService","executed at"+new Date().toString());
			stopSelf();    //Stop service automatically after performing time-consuming tasks. If you don't want to stop service, you can omit this sentence.
		}
	}).start();
}

2. Using IntentService class, the service class has one characteristic: it runs in the sub-thread and stops automatically after running.

Specific usage: Custom subthread service class inherits from IntentService, rewrites MyIntentService and onHandleIntent, and then starts the service

public class MyIntentService extends IntentService{
	public MyIntentService() {
		super("My IntentService");	//Calling the parametric constructor of the parent class
	}
	//Subthread Open Service Processing Specific Logical Method
	@Override
	protected void onHandleIntent(Intent intent) {
		//Processing time-consuming task code
		Log.d("MyIntentService", "Thread is"+Thread.currentThread().getName());
	}
	
}

5. Examples of Timing Tasks Executed in the Background of Services

1. Customize a service that is running all the time and set the timing task through setExact() of Alarm Manager (alarm clock manager). This method receives three parameters:

The first parameter (alarm clock type, four types): ELAPSED_REALTIME (start time from system time, do not wake up CPU)

ELAPSED_REALTIME_WAKEUP (start time from system time, wake up CPU)

RTC (Starting at 0:00 on January 1, 1970, without waking up the CPU)

RTC_WAKEUP (Start from 0:00 on January 1, 1970, wake up CPU)

Second parameter: Timing trigger time (in milliseconds), then the alarm clock is triggered at the start time plus the trigger time point.

The third parameter, Pending Intent, is used to trigger the broadcasting receiver. When the task is triggered, the onReceiver method of the broadcasting receiver is invoked.

The following is an example of obtaining Pending Intent:

        Intent i=new Intent(this,AlarmReceiver.class);
        PendingIntent pi=PendingIntent.getBroadcast(this, 0, i, 0);

2. The onReceiver method of the triggered broadcast receiver restarts the running service and forms a cycle.

// Start Long Running Service after receiving the broadcast
        Intent i=new Intent(context,LongRunningService.class);
        context.startService(i);

Complete examples:

public class LongRunningService extends Service{
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	@TargetApi(Build.VERSION_CODES.KITKAT)
	public int onStartCommand(Intent intent,int flags,int startId) {
		//Open a sub-thread to execute specific background service code
		new Thread(new Runnable() {
			@Override
			public void run() {
				Log.d("LongRunningService","executed at"+new Date().toString());
			}
		}).start();
		AlarmManager manager=(AlarmManager)getSystemService(ALARM_SERVICE);
		int Minute=60*1000;	//It's milliseconds in a minute.
		long triggerTime=SystemClock.elapsedRealtime()+Minute;
		//Alarm Manager sets timer tasks and Alarm Receiver serves as broadcasting receiver for timer tasks.
		Intent i=new Intent(this,AlarmReceiver.class);
		PendingIntent pi=PendingIntent.getBroadcast(this, 0, i, 0);
		manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, pi);
		return super.onStartCommand(intent, flags, startId);
	}
}
public class AlarmReceiver extends BroadcastReceiver{
	@Override
	public void onReceive(Context context, Intent intent) {
		//Start Long Running Service after receiving the broadcast
		Intent i=new Intent(context,LongRunningService.class);
		context.startService(i);
	}

}

 

Keywords: Android

Added by sanju on Fri, 17 May 2019 19:08:50 +0300