简体   繁体   中英

Binding a service from a different APK

I need some help to bound a service by expending the Binder class.

I have 2 APKs. The first one declare a service and I want to bind it from an activity of the second APK.

Both APKs uses the same sharedUserId and the same android:process.

Since they are running in the same process, I don't want to use AIDL for IPC communication (I already try, it's working but I don't want to use it considering I uses only one process).

I can start / bind the service but I can't get the reference to the service :

LocalBinder binder = (LocalBinder);
mService = binder.getService();

I get the exception :

E/AndroidRuntime(6145): java.lang.ClassCastException: 

Is it possible to bound the service by expanding the IBinder class in my case?

Thanks

I've never tried this but I suspect that each .apk is being loaded using its own ClassLoader . This would mean that two identical classes with the same name from each .apk would be regarded as totally different classes by the Dalvik VM.

I believe you will find this impossible to solve.

You should therefore use aidl. I imagine you had two objections to aidl.

  • You probably didn't want to spend time marshalling all your data into Parcelable classes, etc. However, as discussed above, I don't believe you're likely to find a way to pass data directly as Java objects between the two .apks, even when running in the same process, so you have no choice.
  • Perhaps you were worried about performance. But you don't need to worry, because Binder calls (including aidl calls) become just plain function calls when they're in the same process.

Use Messenger: This is the simplest way to perform interprocess communication (IPC), because the Messenger queues all requests into a single thread so that you don't have to design your service to be thread-safe.

If you need your interface to work across different processes(means different APK), you can create an interface for the service with a Messenger. In this manner, the service defines a Handler that responds to different types of Message objects. This Handler is the basis for a Messenger that can then share an IBinder with the client, allowing the client to send commands to the service using Message objects. Additionally, the client can define a Messenger of its own, so the service can send messages back.

If you need your service to communicate with remote processes, then you can use a Messenger to provide the interface for your service. This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.

Here's a summary of how to use a Messenger:

The service implements a Handler that receives a callback for each call from a client. The service uses the Handler to create a Messenger object (which is a reference to the Handler). The Messenger creates an IBinder that the service returns to clients from onBind(). Clients use the IBinder to instantiate the Messenger (that references the service's Handler), which the client uses to send Message objects to the service. The service receives each Message in its Handler—specifically, in the handleMessage() method.

In this way, there are no methods for the client to call on the service. Instead, the client delivers messages (Message objects) that the service receives in its Handler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM