The service does not depend on the interface, and even if the program is switched to the background, the service remains operational. When an application process is killed, any service that relies on that process will also stop running.
The Service is divided into a startup state and a binding state. When in a start-only state, the Service is stopped by StopService or stopself. When you are in a bind state, you need to use Unbindservice and StopService together to stop the Service altogether.
First, service life cycle (OnCreate ()-onstartcommand ()-ondestory ()):
- Whenever Context.startservice () is called from anywhere in the project, the corresponding service is started, OnCreate () is called when it is first created, and then Onstartcommand () is recalled. After the service has started, it remains running until StopService () or stopself () is called.
- OnCreate: It will only be called once when the service is created.
- Onstartcommand: This method is called once for each startservice () call.
- Ondestory: This method is called when StopService or stopself is called.
- Onbind: Callback when calling Bindservice.
Second, how to create a service running in the foreground
The
service runs in the foreground by default, with a low priority and a risk of being recycled when the system is running low on memory. If you do not want to be recycled or are in some need, we can run the service in front of the startforeground.
Below is an example of setting a service as a foreground service, while adding a notification bar when starting the service to see the foreground service running more intuitively, click the notification Bar message to jump to mainactivity.
/** * Front Service */public class Foregroundservice extends service {@Override public void onCreate () {SUPER.O Ncreate (); Shownotification (); } private void Shownotification () {final Notificationcompat.builder Builder = new Notificationcompat.builder (th IS). Setsmallicon (R.mipmap.ic_launcher). Setcontenttitle ("I am Contenttitle"). S Etcontenttext ("I am ContentText"); Create notification when clicked Intent Intent Intent = new Intent (this, mainactivity.class); Create task stack Taskstackbuilder stackbuilder = taskstackbuilder.create (this); Stackbuilder.addparentstack (Mainactivity.class); Stackbuilder.addnextintent (Intent); Pendingintent pendingintent = stackbuilder.getpendingintent (0, pendingintent.flag_update_current); Builder.setcontentintent (pendingintent); Final Notificationmanager Notificationmanager = (notificationmanager) getsystemservice (context.notification_service ); //Build Notification final Notification Notification = Builder.build (); Display notification notificationmanager.notify (0, notification); Start up for front desk service startforeground (0, notification); } @Override Public IBinder onbind (Intent Intent) {throw new unsupportedoperationexception (' not yet implement Ed "); }}
Third, Intentservice and perform time-consuming tasks with service.
While a normal service is running in the background, it does not mean that it is running in a child thread, it is still running in the UI thread. Try to see if the service is running in the UI thread, create a myservice, and add a time-consuming task to its OnCreate method:
public class MyService extends Service {private static final String TAG = MyService.class.getSimpleName (); Omit other code ... @Override public void onCreate () {super.oncreate (); LOG.I (TAG, "OnCreate: Thread:" + thread.currentthread ()); int n = 10; while (n--> 0) {try {thread.sleep (1000); LOG.I (TAG, "I am a time-consuming task to execute the remainder of the period:" + N); } catch (Interruptedexception e) {e.printstacktrace (); }}}}//output: 12-07 14:50:54.683 5506-5506/cn.codingblock.androidadvancestudy i/myservice:oncreate: Thread: Thread[mai n,5,main]12-07 14:50:55.684 5506-5506/cn.codingblock.androidadvancestudy I/myservice: I am a time consuming task, execution remaining time: 912-07 14:50:56.684 5506-5506/cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 812-07 14:50:57.685 5506-5506/cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 712-07 14:50:58.685 5506-5506/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task,Execution time Remaining: 612-07 14:50:59.686 5506-5506/cn.codingblock.androidadvancestudy i/myservice: I am a time-consuming task, execution remaining time: 512-07 14:51:00.686 5506-5506/cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 412-07 14:51:01.687 5506-5506/cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 312-07 14:51:02.687 5506-5506/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 212-07 14:51:03.688 5506-5506/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 112-07 14:51:04.688 5506-5506/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 0
From the log you can see that the name of the thread is Thread[main,5,main] that is the main course, and the program can only perform this time-consuming task in 10s, click on other actions are unresponsive, the successful "stuck". This example illustrates that the normal service runs in the UI thread.
So what if we need to do some time-consuming tasks with the service:
- 1. Open a sub-thread in the normal service and let the child thread perform the time-consuming task.
public class MyService extends Service { private static final String TAG = MyService.class.getSimpleName(); // 省略其他代码... @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate: 线程:" + Thread.currentThread()); new Thread(new Runnable() { @Override public void run() { int n = 10; while (n-- > 0) { try { Thread.sleep(1000); Log.i(TAG, "我是一个耗时任务,执行剩余时间:" + n); Thread.yield(); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); }}
- 2. Use Intentservice to perform time-consuming tasks in the Onhandleintent () method.
public class MyIntentService extends IntentService { String TAG = MyIntentService.class.getSimpleName(); public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { // 这里非主线程,可在这里做一些耗时任务 Log.i(TAG, "onHandleIntent: 线程:" + Thread.currentThread()); int n = 10; while (n-- > 0) { try { Thread.sleep(1000); Log.i(TAG, "我是一个耗时任务,执行剩余时间:" + n); Thread.yield(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
Next in the activity we also create a time-consuming task (maintask) and let the task run on the UI thread, then start MyService, Myintentservice, and Maintask at the same time and observe the log.
public class Servicetestactivity extends Appcompatactivity implements View.onclicklistener {String TAG = Servicetestac Tivity.class.getSimpleName (); Context context; Private Button Btn_start_3_thread; Ignore other code ... @Override public void OnClick (view view) {switch (View.getid ()) {case R. Id.btn_start_3_thread://Start MyService, Myintentservice and Maintask at the same time and observe the log startservice (new Intent (context, myservice.class)); StartService (New Intent (context, myintentservice.class)); Maintask (); Break }} private void Maintask () {int n = 10; while (n--> 0) {try {thread.sleep (1000); LOG.I (TAG, "I am a time-consuming task to execute the remainder of the period:" + N); Thread.yield (); } catch (Interruptedexception e) {e.printstacktrace (); }}}}//input as follows: 12-07 15:08:50.074 22693-22693/cn.codingBlock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 912-07 15:08:51.075 22693-22693/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 812-07 15:08:52.076 22693-22693/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 712-07 15:08:53.076 22693-22693/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 612-07 15:08:54.077 22693-22693/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 512-07 15:08:55.077 22693-22693/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 412-07 15:08:56.078 22693-22693/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 312-07 15:08:57.078 22693-22693/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 212-07 15:08:58.079 22693-22693/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 112-07 15:08:59.079 22693-22693/ Cn.codingblock.androidadvancestudy I/servicetestactivitY: I am a time consuming task, execution remaining: 012-07 15:08:59.095 22693-22693/cn.codingblock.androidadvancestudy i/myservice:oncreate: Threads: thread[main,5,main]12-07 15:08:59.096 22693-22693/cn.codingblock.androidadvancestudy I/MyService: onstartcommand:12-07 15:08:59.102 22693-23358/cn.codingblock.androidadvancestudy i/myintentservice:onhandleintent : Thread: thread[intentservice[myintentservice],5,main]12-07 15:09:00.099 22693-23357/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 912-07 15:09:00.103 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 912-07 15:09:01.100 22693-23357/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 812-07 15:09:01.104 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 812-07 15:09:02.100 22693-23357/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 712-07 15:09:02.104 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 712-07 15:09:03.101 22693-23357/Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 612-07 15:09:03.105 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 612-07 15:09:04.101 22693-23357/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 512-07 15:09:04.105 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 512-07 15:09:05.101 22693-23357/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 412-07 15:09:05.106 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 412-07 15:09:06.102 22693-23357/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 312-07 15:09:06.106 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 312-07 15:09:07.103 22693-23357/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 212-07 15:09:07.107 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining: 212-07 15:09:08.103 22693-23357/CN.CODINGBLock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 112-07 15:09:08.107 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 112-07 15:09:09.103 22693-23357/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 012-07 15:09:09.107 22693-23358/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 0
As can be seen from the log, the first execution of the servicetestactivity in the Maintask time-consuming task to start two Service, test posture seems a bit wrong. Let's start by analyzing the order in which the three lines of code are executed:
// 标记1startService(new Intent(context, MyService.class));startService(new Intent(context, MyIntentService.class));mainTask();
It's supposed to start MyService, start executing the MyService asynchronous task, start Myintentservice and start executing its asynchronous task, and then start the Maintask task, because the first two are asynchronous, So the input result should be three asynchronous tasks cross execution.
But what about the two service that started after the Maintask task was executed from the actual input results?
In fact, this is related to the service start-up process, service startup is more complex, here to say the general process, the general summary of the Service's start-up process has undergone three stages:
- Call Startsesrvice from the app process first;
- Then through the IPC call into the system process (System_service) in AMS (Actvitiymanagerservice) to complete the life cycle management and a series of other work;
- Finally, go back to the app process to complete the service object creation.
The 1th and 3rd steps are performed synchronously, and the 2nd step is performed asynchronously on the service in AMS, leading to the result of the experiment.
Tidy up and re-analyze the three lines of code (marker 1):
- Call the first line of StartService to start MyService, which is performed synchronously until the AMS phase begins to execute asynchronously, and there is an opportunity to execute the second line of StartService code in the main thread. Ext. 2
- In the same vein as 1, the execution to the AMS phase starts asynchronously when Myintentservice is started, and there is an opportunity to execute the third line of code. Ext. 3
- Calling the Maintask () method starts the time-consuming task of executing the main thread, which is synchronous, so that the front-end of the task is not toggled. Even though the above two start-up service methods have been performed by AMS, when the main thread is moved to the main thread, it is time-consuming to execute the maintask, it can only wait for it to complete, then create the service and then open the asynchronous task in two service.
Well, the reason has been ascertained. There are surprises everywhere, there is a harvest everywhere!
The solution to the above problem is very simple, that is, after the service startup is completed, we call the activity of the Maintask () method, such as using two buttons to control, the modified output log as follows:
12-07 17:53:10.905 29898-29898/cn.codingblock.androidadvancestudy i/myservice:oncreate: Thread: Thread[main,5,main] 12-07 17:53:10.910 29898-29898/cn.codingblock.androidadvancestudy i/myservice:onstartcommand:12-07 17:53:10.916 29898-30563/cn.codingblock.androidadvancestudy i/myintentservice:onhandleintent: Thread: Thread[IntentService[ myintentservice],5,main]12-07 17:53:11.907 29898-30561/cn.codingblock.androidadvancestudy I/MyService: I'm a time-consuming task, Execution time Remaining: 912-07 17:53:11.916 29898-30563/cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, Execution time Remaining: 912-07 17:53:12.824 29898-29898/cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, Execution time Remaining: 912-07 17:53:12.907 29898-30561/cn.codingblock.androidadvancestudy i/myservice: I am a time-consuming task, execution remaining time: 812-07 17:53:12.916 29898-30563/cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 812-07 17:53:13.825 29898-29898/cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 812-07 17:53:13.908 29898-30561/cn.codIngblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 712-07 17:53:13.917 29898-30563/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 712-07 17:53:14.826 29898-29898/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 712-07 17:53:14.910 29898-30561/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 612-07 17:53:14.918 29898-30563/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 612-07 17:53:15.827 29898-29898/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 612-07 17:53:15.911 29898-30561/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 512-07 17:53:15.919 29898-30563/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 512-07 17:53:16.827 29898-29898/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 512-07 17:53:16.912 29898-30561/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 412-07 17:53:16.920 29898-30563/cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 412-07 17:53:17.828 29898-29898/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 412-07 17:53:17.913 29898-30561/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 312-07 17:53:17.922 29898-30563/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 312-07 17:53:18.829 29898-29898/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 312-07 17:53:18.914 29898-30561/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 212-07 17:53:18.923 29898-30563/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 212-07 17:53:19.829 29898-29898/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 212-07 17:53:19.915 29898-30561/ Cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 112-07 17:53:19.924 29898-30563/ Cn.codingblock.androidadvancestudy I/myintentservice: I am a time consuming task, execution remaining time: 112-07 17:53:20.830 29898-29898/cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 112-07 17:53:20.916 29898-30561/cn.codingblock.androidadvancestudy I/myservice: I'm a time-consuming task, execution remaining time: 012-07 17:53:20.924 29898-30563/ Cn.codingblock.androidadvancestudy I/myintentservice: I'm a time-consuming task, execution remaining time: 012-07 17:53:21.830 29898-29898/ Cn.codingblock.androidadvancestudy i/servicetestactivity: I'm a time-consuming task, execution remaining time: 0
From the log, the time-consuming tasks of starting a child thread in the normal service and the tasks in the Intentservice and the tasks in the main thread are indeed cross-executing.
Finally want to say is, this series for Bo master on Android knowledge again comb, check the learning process, on the one hand is forgetting things to review again, on the other hand believe in the process of re-learning will have a huge new harvest, if you also have with me the same idea, may wish to pay attention to my study together , explore each other and make progress together!
Reference documents:
- Explore the art of Android development
- "Android Development advanced from small to expert"
Android Check Gaps--service and Intentservice