Giao tiếp giữa Activity và Service trong Android với IBinder interface

Trong quá trình phát triển ứng dụng, có những trường hợp cần sự giao tiếp giữa Activity và Service.

Có các phương pháp để giao tiếp giữa Activity và Service khác nhau, ví dụ như:

  • IBinder interface
  • BroadcastReceiver, LocalBroadcastReceiver. Tham khảo bài viết tại link này

Việc sử dụng IBinder interface, có 3 cách để định nghĩa và sử dụng:

  1. Kế thừa Binder class
  2. Sử dụng Messenger và Handler
  3. Sử dụng Android Interface Definition Language (AIDL)

 

Cách 1: Kế thừa Binder class

Bước 1: Định nghĩa callback để Service sử dụng.

public interface ServiceCallbacks {

void doSomething();

}

Bước 2: Sử dụng một ServiceConnection để nắm bắt trạng thái Service. Từ đó có thể truyền callback vào Service.

Ta có một Service class đơn giản

public class MyService extends Service {
// Binder given to clients
private final IBinder binder = new LocalBinder();
// Registered callbacks
private ServiceCallbacks serviceCallbacks;

 

// Class used for the client Binder.
public class LocalBinder extends Binder {
MyService getService() {
// Return this instance of MyService so clients can call public methods
return MyService.this;
}
}

@Override
public IBinder onBind(Intent intent) {
return binder;
}

public void setCallbacks(ServiceCallbacks callbacks) {
serviceCallbacks = callbacks;
}
}

Bước 3: Bind Service trong Activity

public class MyActivity extends Activity implements ServiceCallbacks {
private MyService myService;
private boolean bound = false;

@Override
protected void onStart() {
super.onStart();
// bind to Service
Intent intent = new Intent(this, MyService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
super.onStop();
// Unbind from service
if (bound) {
myService.setCallbacks(null); // unregister
unbindService(serviceConnection);
bound = false;
}
}

/** Callbacks for service binding, passed to bindService() */
private ServiceConnection serviceConnection = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// cast the IBinder and get MyService instance
LocalBinder binder = (LocalBinder) service;
myService = binder.getService();
bound = true;
myService.setCallbacks(MyActivity.this); // register
}

@Override
public void onServiceDisconnected(ComponentName arg0) {
bound = false;
}
};

/* Defined by ServiceCallbacks interface */
@Override
public void doSomething() {

}
}

Bước 4: Sử dụng callback trong Service

if (serviceCallbacks != null) {
serviceCallbacks.doSomething();
}

Vậy là đã có thể gọi functions của Activity từ Service.

Đây là một phương pháp khá hay và được sử dụng rộng rãi.

Lưu ý:

Như các bạn đã biết, Service có thể được chạy trên một process khác.

Phương pháp này chỉ có thể sử dụng khi Activity và Service được chạy cùng một process mà thôi.

 

Cách 2: Sử dụng Messenger và Handler

Nếu Service của bạn cần giao tiếp với remote process, bạn có thể sử dụng Messenger để cung cấp interface cho Service của bạn.

Kỹ thuật này cho phép bạn thực hiện interprocess communication (IPC)

Ví dụ:
There is a simple example service that use a Messenger interface.
1. Service implements a Handler that receives a callback for each call from client.
2. Service uses the Handler to create a Messenger object (which is a reference to the Handler).
3. The Messenger creates an IBinder that the service returns to client from onBind()
4. Client uses the IBinder to instantiate the Messenger (that references the service’s Handler)
which client uses to send Message object to the serive.
5. The service retrieves each Message in its Handler – specifically, in the handleMessage() method.

Cách 3: Sử dụng Android Interface Definition Language (AIDL)

AIDL allows you to difine the programming interface that both the client and service agree upon in order to communicate
with each other using interprocess communication (IPC).

On Android, one process can not normally access the memory of another process.
So to talk, the need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary with AIDL

===> Defining an AIDL Interface
AIDL Interface is an .aidl file using Java syntax.
Then, save it in the source code in the src/ directory of both the application hosting the service and any other application that binds to the service.
When you build your application, the SDK tools generate the IBinder interface file in your project’s gen/ directory.
Example: IRemoteSerive.aidl -> IRemoteService.java
===> Implement the interface
The generated interface includes a subclass named Stub that is an abstract implementation of its parent interface and declares all the methods from the .aidl file.
Now, when client (sach as a Activity) call bindService() to connect to this service, the client’s onServiceConnected() callback receives the mBinder instance returned
by the service’s onBind() method.

Phía trên là cách sử dụng IBinder interface để giao tiếp giữa Activity và Service.

Hết.

Advertisement

Share this:

Like this:

Like

Loading…