Use of Local Service and Binder
Local Service and Active communication can be implemented by Binder, inherited in Service first. Binder Implement your own Binder class.
-
class MyBinder extends Binder {
-
public LocalBindService getService() {
-
return LocalBindService.this;
-
}
-
}
Then in Service onBind() Return to this Binder Examples.
-
@Override
-
public IBinder onBind(Intent intent) {
-
Log.i(TAG,"onBind");
-
doSomeTask();
-
return mMyBinder;
-
}
In Activity, through onServiceConnected() Obtain Binder Examples are from Binder Instances give service instances. This can call public methods in Service, but sometimes it is necessary for Service to notify Activity actively to do some UI updating operations. At this point, we need to define an interface in Service, which can then be used by Service to call back the methods in Activity.
-
interface ProgressChangeListener {
-
void updateProgress(int value);
-
}
-
-
public void setProgressChangeListener(ProgressChangeListener progressChangeListener) {
-
mProgressChangeListener = progressChangeListener;
-
}
In Activity:
-
private ServiceConnection mConnection = new ServiceConnection() {
-
@Override
-
public void onServiceDisconnected(ComponentName name) {
-
-
}
-
-
@Override
-
public void onServiceConnected(ComponentName name, IBinder service) {
-
LocalBindService.MyBinder myBinder = (LocalBindService.MyBinder) service;
-
LocalBindService localBindService =myBinder.getService();
-
-
localBindService.setProgressChangeListener(new LocalBindService.ProgressChangeListener() {
-
@Override
-
public void updateProgress(int value) {
-
mBindProgressBar.setProgress(value);
-
}
-
});
-
}
-
};
Communication with remote processes via Messenger
Messenger enables Service to communicate with remote processes. Messenger All requests in the queue are placed in a single thread, so the Service can only process one request at a time.
1. Service implements a Handler To receive and process messages sent by clients.
-
class MessengerHandler extends Handler {
-
@Override
-
public void handleMessage(Message msg) {
-
switch (msg.what) {
-
case MSG_REGISTER_CLIENT:
-
mClients.add(msg.replyTo);
-
break;case MSG_UNREGISTER_CLIENT:
-
try {
-
msg.replyTo.send(Message.obtain(null,
-
MSG_UNREGISTER_CLIENT, 8888, 0));
-
} catch (RemoteException e) {
-
e.printStackTrace();
-
}
-
mClients.remove(msg.replyTo);
-
break;case MSG_SET_VALUE:
-
mValue = msg.arg1;
-
for (int i = mClients.size() - 1; i >= 0; i--) {
-
try {
-
mClients.get(i).send(Message.obtain(null,
-
MSG_SET_VALUE, mValue, 0));
-
} catch (RemoteException e) {
-
mClients.remove(i);
-
}
-
}
-
break;default:
-
super.handleMessage(msg);
-
}
-
}
-
}
2. Create a reference containing Handler Messenger Object.
-
private MessengerHandler mMessengerHandler = new MessengerHandler();
-
private Messenger mMessenger = new Messenger(mMessengerHandler);
3. Pass Messenger Get Binder And from onBind() Method returns it.
-
@Override
-
public IBinder onBind(Intent intent) {
-
return mMessenger.getBinder();
-
}
4. In Service Connection, the client uses IBinder To instantiate this Messenger Use this. Messenger Send to Service Message Object, Service
Handler will process this Message object in the.http://http://http://http://http://http://http://http://ht
- private ServiceConnection mServiceConnection=new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mMessengerService=new Messenger(service);
- mCallbackText.setText("Attached.");
- try {Message msg = Message.obtain(null,
- MessengerService.MSG_REGISTER_CLIENT);
- msg.replyTo = mMessenger;
- mMessengerService.send(msg);
- msg = Message.obtain(null,
- MessengerService.MSG_SET_VALUE, this.hashCode(), 0);
- mMessengerService.send(msg);
- } catch (RemoteException e) {
-
- } Toast.makeText(MessengerActivity.this, "remote_service_connected",
- Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- mCallbackText.setText("Disconnected.");
- Toast.makeText(MessengerActivity.this, "remote_service_disconnected",
- Toast.LENGTH_SHORT).show();
- }
- };
5. The client also defines a Handler object to handle the Message object returned by the server and constructs a handler referenceMessenger Object, when sending a message to the server, the client's Messenger Objects assigned to messagesreplyTo In this way, the server sends the Message object to the client through replyTo.
In this way, the client and the server can pass Message objects to each other.
-
<span style="font-size:14px;">private Handler mHandler=new Handler(){
-
@Override
-
public void handleMessage(Message msg) {
-
switch (msg.what) {
-
case MessengerService.MSG_SET_VALUE:
-
mCallbackText.setText("Received from service: " + msg.arg1);
-
break; case MessengerService.MSG_UNREGISTER_CLIENT:
-
Toast.makeText(MessengerActivity.this, "Received from service: "+msg.arg1,
-
Toast.LENGTH_SHORT).show();
-
default:
-
super.handleMessage(msg);
-
}
-
}
-
};
-
-
private Messenger mMessenger=new Messenger(mHandler);</span>
Communication with remote processes via AIDL
AIDL(Android Interface Definition Language (IDL) is the meaning of Android Interface Definition Language (IDL). It can be used to enable a Service to communicate across processes with multiple application components, thus enabling multiple applications to share the same Service.
If a Service is required to receive multiple requests at the same time, Messenger cannot meet the requirement and needs to use AIDL. In this case, the Service must be able to execute multiple threads and must be thread-safe for the Service.
1. Create a. aidl
AIDL parameters and return values can be of any type, or even other AIDL-generated interfaces. Use Java Language builds a. aidl file, each. aild file must define a separate interface, and use a definite declaration and method signature.
-
/ IRemoteService.aidl
-
package com.example.xujiang.servicelearn;
-
import com.example.xujiang.servicelearn.IRemoteServiceCallback;
-
-
-
interface IRemoteService {
-
void registerCallback(IRemoteServiceCallback cb);
-
-
void unregisterCallback(IRemoteServiceCallback cb);
-
}
2. Inheritance of this interface
The Android SDK tool generates an interface for. aidl files. This interface has an internal abstract class called Stub. You need to write a class that inherits the Stub class and implements these methods, returning instance objects of the class in onBind.
-
private final IRemoteService.Stub mRemoteServiceStub=new IRemoteService.Stub() {
-
@Override
-
public void registerCallback(IRemoteServiceCallback cb) throws RemoteException {
-
if (cb!=null){
-
mCallbacks.register(cb);
-
}
-
}
-
-
@Override
-
public void unregisterCallback(IRemoteServiceCallback cb) throws RemoteException {
-
if (cb!=null){
-
mCallbacks.unregister(cb);
-
}
-
}
-
};
3. Exposing the interface to the client
Inherit a Service and override onBind() to return the implemented Stub class. The client gets the reference of the interface through the asInterface method, so it can call the method in the interface.
If you need to pass classes between processes, classes must support the Parcelable interface. Parcelable interfaces are supported because Android systems need to decompose objects into primitives that can traverse processes.
-
@Override
-
public IBinder onBind(Intent intent) {
-
Log.i(TAG,"onBind");
-
return mRemoteServiceStub;
-
}
4. Client Call
-
private ServiceConnection mConnection = new ServiceConnection() {
-
public void onServiceConnected(ComponentName className,
-
IBinder service) {
-
mRemoteService = IRemoteService.Stub.asInterface(service);
-
mCallbackText.setText("Attached.");
-
try {
-
mRemoteService.registerCallback(mServiceCallback);
-
} catch (RemoteException e) {
-
}Toast.makeText(AIDLActivity.this, "remote_service_connected",
-
Toast.LENGTH_SHORT).show();
-
}
-
-
public void onServiceDisconnected(ComponentName className) {
-
mRemoteService = null;
-
mCallbackText.setText("Disconnected.");
-
Toast.makeText(AIDLActivity.this, "remote_service_disconnected",
-
Toast.LENGTH_SHORT).show();
-
}
-
};