Explain in detail the precautions when using Android service

Recently, a project just used service, especially Aidl remote service. After this project, we have a better understanding of service. Here is a summary.

Startservice / bindservice mixed use

If startservice / bindservice are mixed, what will happen to the life synchronization of service? In fact, as long as you remember the above ideas, this problem is easy to understand. First, startservice corresponds to stopservice. Without stopservice, there will be no destroy service. Bindservice corresponds to unbindservice. Without unbindservice, there will be no destroy service.

Add permissions to the service

I believe the services we do are public, that is, all applications can call. But if I want my service to only call specific applications, how should I set it? We can add permissions to the service. As for permissions, the Android system gives permissions to four categories:

If we want our own services to be called only by specific clients, we can add custom permissions. For example, for danger level, we can declare the corresponding permission in androidmanifest.xml. Only when the application also sets this permission can the service be started normally.

About Aidl remote services

The so-called Aidl remote service is a service running in another process. Usually, the services we call run in the main thread. To use Aidl service, you must write Aidl interface, and expose the interface to the outside to interact with the remote service. There are several noteworthy points about Aidl:

How to upgrade the Aidl interface?

When working on a large-scale project, the project will continue to iterate, so it is possible to add and modify Aidl interfaces. How to ensure that Aidl interfaces and old interfaces will not be confused? According to my experience, I have the following summary:

Service manages multiple clients

If the service has multiple clients, how to communicate with them safely? How to give callback results to each client? Here I want to talk about a problem that occurred in my recent project. I want to do a public service in the project, which is similar to fingerprint unlocking. Other applications get results by calling my service. I designed two interfaces: start (callback) and stop (). At the beginning, I used a single callback, that is, I defined a callback attribute in the code, Set the callback to whoever calls start. Only the last client calling start can get a callback. The code is as follows:

This method is very effective in a single application. In multiple applications, as long as the application can execute start and stop in order, there is no problem with the design of this interface. But things are not as simple as expected. If client1 calls start and client2 calls start, then client1 wants to stop. What happens? The whole service stops. This is a big problem in the service I designed. Later, I want to make some changes to my service interface to adapt to the non sequential invocation of multiple applications. My first idea is to use register and unregister to collect all callbacks with a list. During callback, you can cycle. During stop, you can also judge the number of lists. If it is less than or equal to 1, execute stop:

Considering the interface upgrade, this change is minimal. Only one parameter is added to stop. However, there are also problems with this method. The reference of our service to callback is a strong reference. If the client exits abnormally, the reference will still exist and accumulate more and more. During callback, the error of deadobjectexception may also occur. Through searching for information on the network, I found the remotecallbacklist, which is also a list. It stores the callback interface. It uses the link to death callback (it receives the binder object in the service and uses binder. Linktodeath()) to register a deathrecipient callback and implement deathrecipient. When the client exits unexpectedly, deathrecipient.binderdied () will be called back, and we can release relevant resources here.) the final code is as follows:

Use messenger to communicate between servie and client

Messenger is based on a handler. It adds a handler to messenger to transfer processing data. After that, the communication between the service and the client is carried out through the transferred handler. In this way, there is no need to define Aidl interface, and there is no trouble of interface version mismatch caused by modifying Aidl interface.

Messenger is used to deliver messages through the handler. The send method of the client sends a message. This message.replyto points to a messenger. Messenger also holds a binder object (messengerimpl) of the client. The server uses this binder object to communicate with the client.

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>