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); } }