This is the third in our interview series. In this installment, we’ll take a look at an important part of Android’s four components: Services.

How to understand the lifecycle of an Activity Android Interview (3) : Is it really a good idea to update the UI with BroadcastReceiver?

How important is Service?

This is an interesting scenario I saw in the article “Lanliu Learning”. Let’s share it with you and see how much trouble ignorance of Service can cause.

Scenario: If an application downloads a file from the network and displays a progress bar on the Activity, the Activity must be screenable. Actvitiy will restart during screen rotation. How do YOU ensure that the downloaded progress bar displays the correct progress?

People who don’t know Service usually come up with something like this.

  • Cache the progress before turning the screen, and read it out after turning the screen.

  • Using the Android :configChanges setting, the Activity does not destroy or rebuild during screen transitions.

In view of the first scheme, there are many loopholes. First of all, during the screen rotation process, we know that the Activity reconstruction is time-consuming, may take hundreds of milliseconds or more, at this time, the download thread is still working, the progress must be inconsistent with the progress of the save. How to deal with this problem?

The second option is for you to think about for yourself, but in a real project you might need to do something extra to deal with the vertical and horizontal layout of the ContentView.

Do you have any ideas for using services? Let us know in the comments section.

You’ve heard of Service. How many ways does it start?

A Service is a class that executes operations in the background and does not interact with the user’s UI. It provides two boot options.

  • Started Another component calls startService() to start a Service. Once started, a Service runs in the background, even if the component that started it has been destroyed. Usually a Service that is started performs a separate operation in the background and does not need to return a result to the component that started it. It terminates only when the Service itself calls stopSelf() or when another component calls stopService().

  • Bind Other components can call bindService() to bind a Service. This will bind the Service to the component that started it, and the Service will automatically unBind when the component that started it is destroyed. A Service can be bound by multiple components. A Service is destroyed only when all the components to which it is bound are unBind.

Of course, a Service can also run in both ways. This involves the execution of two callback methods of the Service: onStartCommand() (the callback method used to start a Service). OnBind () (a method to initiate a Service callback by bind).

No matter how you start a Service (start, bind, start & bind), any component (even components of other applications) can use a Service. Parameters are passed through the Intent. Of course, you can also make the Service private in the AndroidMenifest. XML file and not allow other applications to access it.

The Android :exported attribute is set to false to not allow other applications to launch components of the app, even when using an explicit Intent. This prevents other applications from starting your Service component.

The Service life cycle

When it comes to components, we always like to study their life cycle, and this is certainly the best time to show it in a diagram.

The two paths are not unrelated. When callingstartService()After starting a Service, you can still bind the Service. For example, when playing music, you need to callstartService()Start the specified music, when the need to obtain the music playback progress, and need to callbindService()In this case, unless the Service is unbind, previously calledstopService()stopSelf()The Service cannot be stopped.

These lifecycle methods do not need to call their parent methods when they are used.

Both lifecycle paths can contain two nested lifecycles:

  • Entire lifetime: from onCreate() called to onDestroy() returned. Similar to activities, some initialization is done in the onCreate() method and some resource release is done in onDestroy(). For example, if a Service plays a music in the background, it needs to start a thread in the onCreate() method to start the music and end the thread in onDestroy().

  • Activity Lifetime: Starts with the onStartCommand() or onBind() callback and is invoked by the corresponding startService() or bindService(). The end of the activity cycle of start means the end of the full proof cycle, while the end of the activity cycle of bind, when onUnbind() returns, means the end of the activity cycle of the Service.

It is worth noting that both onCreate() and onDestroy() are called back whether startService() or bindService() starts the Service.

Can Service onCreate() perform time-consuming operations?

The Service runs in the main thread. It is not a new thread, nor is it a new process, so it cannot perform time-consuming operations.

What if you want to perform a time-consuming operation in a Service?

I think almost everyone can think of using Thread, and in fact we often do. You need to perform time-consuming operations on the main thread, which is nothing more than opening a thread and then a flurry of operations. Of course, you can also use AysncTask or HandlerThread to create threads instead of threads.

Of course not. Is there a more interesting way?

Yes, of course, IntentService is a good one.

Complex intentServices

IntentService inherits from Service. If a Service does not need to handle multiple requests at the same time, IntentService is the best choice. You just override the onHandleIntent() method, which accepts an Intent parameter that calls back. You can do time-consuming operations inside the method because it starts a child thread by default, and you don’t need to manually call stopSelf() when the action is finished. OnHandleIntent () will call this method automatically.

The main points of using IntentService are as follows:

  • By default, intents returned to the onStartCommand() method are handled in child threads;

  • The overwritten onHandleIntent() method handles time-sorted Intent queues, so you don’t have to worry about multi-threading.

  • When all requests are processed, the Service is stopped automatically, without manually calling the stopSelf() method.

  • The onBind() method is implemented by default and returns NULL;

  • The onStartCommand() method is implemented by default and the returned Intent is sent as a sequence to onHandleIntent(). You simply override the method and handle the Intent.

summary

When we know the purpose of Service and have a service-related concept in mind, we still need to make a specific analysis according to the actual scenario before deciding whether to use Service. Because the Service is still called in the main thread and has to be opened to handle long hours of work, the interaction between the Service and the UI makes this approach difficult. If you only need to perform time-consuming operations on the current interface and work stops when the interface exits or changes, then using Thread (or AsyncTask, ThreadHandler) directly is more appropriate.


Welcome to follow nanchen’s official account: Nanchen if you like, you can choose to share with everyone. If you have a good article, welcome to contribute, praise all belong to you.

Long press the qr code above to pay attention

Do not finish the open source, write not finish hypocritical

Let’s take a look at Nanchen’s growth notes