lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Dịch vụ Gắn kết

Dịch vụ gắn kết là máy chủ trong một giao diện máy khách-máy chủ. Dịch vụ gắn kết cho phép các thành phần (chẳng hạn như các hoạt động) gắn kết với dịch vụ, gửi yêu cầu, nhận phản hồi, và thậm chí thực hiện truyền thông liên tiến trình (IPC). Dịch vụ gắn kết thường chỉ hoạt động khi nó phục vụ một thành phần ứng dụng khác và không chạy ngầm mãi liên tục.

Tài liệu này cho bạn biết cách tạo một dịch vụ gắn kết, bao gồm cách gắn kết với dịch vụ từ các thành phần ứng dụng khác. Tuy nhiên, bạn cũng nên tham khảo tài liệu Dịch vụ để biết thêm thông tin về các dịch vụ nói chung, chẳng hạn như cách gửi thông báo từ một dịch vụ, đặt dịch vụ để chạy trong tiền cảnh, và nhiều nội dung khác.

Nội dung Cơ bản

Dịch vụ gắn kết là một sự triển khai lớp Service cho phép các ứng dụng khác gắn kết và tương tác với nó. Để thực hiện gắn kết cho một dịch vụ, bạn phải triển khai phương pháp gọi lại onBind(). Phương pháp này trả về một đối tượng IBinder định nghĩa giao diện lập trình mà các máy khách có thể sử dụng để tương tác với dịch vụ.

Một máy khách có thể gắn kết với dịch vụ bằng cách gọi bindService(). Khi làm vậy, nó phải cung cấp việc triển khai ServiceConnection, có chức năng theo dõi kết nối với dịch vụ. Phương pháp bindService() trả về ngay lập tức mà không có giá trị, nhưng khi hệ thống Android tạo kết nối giữa máy khách và dịch vụ, nó gọi onServiceConnected() trên ServiceConnection, để giao IBinder mà máy khách có thể sử dụng để giao tiếp với dịch vụ.

Nhiều máy khách có thể kết nối với dịch vụ đồng thời. Tuy nhiên, hệ thống sẽ gọi phương pháp onBind() của dịch vụ của bạn để truy xuất IBinder chỉ khi máy khách đầu tiên gắn kết. Sau đó, hệ thống sẽ giao cùng một IBinder đó cho bất kỳ máy khách bổ sung nào có gắn kết mà không gọi lại onBind().

Khi máy khách cuối cùng bỏ gắn kết với dịch vụ, hệ thống sẽ hủy dịch vụ (trừ khi dịch vụ cũng được bắt đầu bởi startService()).

Khi bạn triển khai dịch vụ gắn kết của mình, phần quan trọng nhất là định nghĩa giao diện mà phương pháp gọi lại onBind() của bạn sẽ trả về. Có một vài cách khác nhau mà bạn có thể định nghĩa giao diện IBinder của dịch vụ của mình và phần sau đây sẽ bàn về từng kỹ thuật.

Tạo một Dịch vụ Gắn kết

Khi tạo một dịch vụ thực hiện gắn kết, bạn phải nêu một IBinder cung cấp giao diện lập trình mà các máy khách có thể sử dụng để tương tác với dịch vụ. Có ba cách bạn có thể định nghĩa giao diện:

Mở rộng lớp Trình gắn kết
Nếu dịch vụ của bạn chỉ riêng cho ứng dụng của chính bạn và chạy trong cùng tiến trình như máy khách (điều này thường hay gặp), bạn nên tạo giao diện của mình bằng cách mở rộng lớp Binder và trả về một thực thể của nó từ onBind(). Máy khách nhận được Binder và có thể sử dụng nó để trực tiếp truy cập các phương pháp công khai có sẵn trong triển khai Binder hoặc thậm chí trong Service.

Nên áp dụng kỹ thuật này khi dịch vụ của bạn chỉ là một trình thực hiện chạy ngầm cho ứng dụng của chính bạn. Lý do duy nhất bạn không nên tạo giao diện của mình bằng cách này đó là dịch vụ của bạn được sử dụng bởi các ứng dụng khác hoặc giữa những tiến trình khác nhau.

Sử dụng một Hàm nhắn tin
Nếu bạn cần giao diện của mình thực hiện các tiến trình khác nhau, bạn có thể tạo một giao diện cho dịch vụ bằng Messenger. Bằng cách này, dịch vụ định nghĩa một Handler phản hồi các loại đối tượng Message khác nhau. Handler này là cơ sở cho một Messenger mà sau đó có thể chia sẻ một IBinder với máy khách, cho phép máy khách gửi lệnh tới dịch vụ bằng cách sử dụng các đối tượng Message. Ngoài ra, máy khách có thể định nghĩa Messenger của chính nó để dịch vụ có thể gửi lại thông báo.

Đây là cách đơn giản nhất để thực hiện truyền thông liên tiến trình (IPC), vì Messenger xếp hàng tất cả yêu cầu thành một luồng duy nhất sao cho bạn không phải thiết kế dịch vụ của mình an toàn với luồng.

Sử dụng AIDL
AIDL (Ngôn ngữ Định nghĩa Giao diện Android) thực hiện tất cả công việc để phân tách đối tượng thành các phần tử mà hệ điều hành có thể hiểu được và ghép nối chúng qua các tiến trình để thực hiện IPC. Bằng cách sử dụng Messenger, kỹ thuật trước đó thực tế được dựa trên AIDL như là cấu trúc cơ bản của nó. Như đã đề cập bên trên, Messenger tạo một hàng chờ gồm tất cả yêu cầu của máy khách trong một luồng duy nhất, vì thế dịch vụ nhận được từng yêu cầu một. Tuy nhiên, nếu bạn muốn dịch vụ xử lý nhiều yêu cầu đồng thời, bạn có thể sử dụng AIDL trực tiếp. Trong trường hợp này, dịch vụ của bạn phải có khả năng tạo đa luồng và được xây dựng an toàn với luồng.

Để sử dụng AIDL trực tiếp, bạn phải tạo một tệp .aidl định nghĩa giao diện lập trình. Các công cụ SDK Android sử dụng tệp này để khởi tạo một lớp tóm tắt (abstract class) nhằm triển khai giao diện và xử lý IPC, mà sau đó bạn có thể mở rộng trong dịch vụ của mình.

Lưu ý: Hầu hết ứng dụng không nên sử dụng AIDL để tạo một dịch vụ gắn kết, vì nó có thể yêu cầu khả năng tạo đa luồng và có thể dẫn đến việc triển khai phức tạp hơn. Như vậy, AIDL không phù hợp với hầu hết ứng dụng và tài liệu này không bàn về cách sử dụng nó cho dịch vụ của bạn. Nếu bạn chắc chắn rằng mình cần sử dụng AIDL trực tiếp, hãy xem tài liệu AIDL .

Mở rộng lớp Trình gắn kết

Nếu dịch vụ của bạn chỉ được sử dụng bởi ứng dụng cục bộ và không cần làm việc qua nhiều tiến trình, khi đó bạn có thể triển khai lớp Binder của chính mình để cung cấp quyền truy cập trực tiếp cho máy khách của bạn để truy nhập các phương pháp công khai trong dịch vụ.

Lưu ý: Cách này chỉ có tác dụng nếu máy khách và dịch vụ nằm trong cùng ứng dụng và tiến trình, là trường hợp phổ biến nhất. Ví dụ, cách này sẽ hoạt động tốt đối với một ứng dụng nhạc cần gắn kết một hoạt động với dịch vụ của chính nó đang phát nhạc chạy ngầm.

Sau đây là cách thiết lập:

  1. Trong dịch vụ của bạn, hãy tạo một thực thể Binder mà hoặc:
    • chứa các phương pháp công khai mà máy khách có thể gọi
    • trả về thực thể Service hiện tại, trong đó có các phương pháp công khai mà máy khách có thể gọi
    • hoặc, trả về một thực thể của một lớp khác được lưu trữ bởi dịch vụ bằng các phương pháp công khai mà máy khách có thể gọi
  2. Trả về thực thể Binder này từ phương pháp gọi lại onBind().
  3. Trong máy khách, nhận Binder từ phương pháp gọi lại onServiceConnected() và thực hiện gọi tới dịch vụ gắn kết bằng cách sử dụng các phương pháp đã nêu.

Lưu ý: Lý do dịch vụ và máy khách phải ở trong cùng ứng dụng đó là máy khách có thể đổi kiểu đối tượng được trả về và gọi các API của nó một cách phù hợp. Dịch vụ và máy khách cũng phải ở trong cùng tiến trình, vì kỹ thuật này không thực hiện bất kỳ thao tác ghép nối qua các tiến trình nào.

Ví dụ, sau đây là một dịch vụ cung cấp cho máy khách quyền truy cập các phương pháp trong dịch vụ thông qua việc triển khai Binder:

public class LocalService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    // Random number generator
    private final Random mGenerator = new Random();

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

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

    /** method for clients */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}

LocalBinder cung cấp phương pháp getService() cho máy khách để truy xuất thực thể hiện tại của LocalService. Điều này cho phép máy khách gọi các phương pháp công khai trong dịch vụ. Ví dụ, máy khách có thể gọi getRandomNumber() từ dịch vụ.

Sau đây là một hoạt động gắn kết với LocalService và sẽ gọi getRandomNumber() khi nhấp vào nút:

public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to LocalService
        Intent intent = new Intent(this, LocalService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }

    /** Called when a button is clicked (the button in the layout file attaches to
      * this method with the android:onClick attribute) */
    public void onButtonClick(View v) {
        if (mBound) {
            // Call a method from the LocalService.
            // However, if this call were something that might hang, then this request should
            // occur in a separate thread to avoid slowing down the activity performance.
            int num = mService.getRandomNumber();
            Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
        }
    }

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

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

Mẫu trên cho thấy cách mà máy khách gắn kết với dịch vụ bằng cách sử dụng triển khai ServiceConnection và gọi lại onServiceConnected(). Phần tiếp theo cung cấp thêm thông tin về tiến trình gắn kết này với dịch vụ.

Lưu ý: Ví dụ trên không công khai bỏ gắn kết khỏi dịch vụ, nhưng tất cả máy khách cần bỏ gắn kết tại một thời điểm phù hợp (chẳng hạn như khi hoạt động tạm dừng).

Để biết thêm mã ví dụ, hãy xem lớp LocalService.java và lớp LocalServiceActivities.java trong ApiDemos.

Sử dụng một Hàm nhắn tin

Nếu bạn cần dịch vụ của mình giao tiếp với các tiến trình từ xa, khi đó bạn có thể sử dụng một Messenger để cung cấp giao diện cho dịch vụ của mình. Kỹ thuật này cho phép bạn thực hiện truyền thông liên tiến trình (IPC) mà không cần sử dụng AIDL.

Sau đây là tóm tắt cách sử dụng Messenger:

  • Dịch vụ triển khai Handler để nhận lệnh gọi lại cho mỗi lệnh gọi từ một máy khách.
  • Handler được sử dụng để tạo một đối tượng Messenger (là một tham chiếu tới Handler).
  • Messenger tạo một IBinder mà dịch vụ trả về máy khách từ onBind().
  • Máy khách sử dụng IBinder để khởi tạo Messenger (tham chiếu tới Handler của dịch vụ), mà máy khách sử dụng để gửi các đối tượng Message tới dịch vụ.
  • Dịch vụ nhận được từng Message trong Handler của mình—cụ thể là theo phương pháp handleMessage().

Theo cách này, không có "phương pháp" nào để máy khách gọi đối với dịch vụ. Thay vào đó, máy khách gửi “thông báo” (đối tượng Message) mà dịch vụ nhận được trong Handler của mình.

Sau đây là một dịch vụ ví dụ đơn giản sử dụng một giao diện Messenger:

public class MessengerService extends Service {
    /** Command to the service to display a message */
    static final int MSG_SAY_HELLO = 1;

    /**
     * Handler of incoming messages from clients.
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
}

Để ý rằng phương pháp handleMessage() trong Handler là nơi dịch vụ nhận được Message đến và quyết định việc cần làm dựa trên thành viên what.

Tất cả việc mà một máy khách cần làm đó là tạo một Messenger dựa trên IBinder được dịch vụ trả về và gửi một thông báo bằng cách sử dụng send(). Ví dụ, sau đây là một hoạt động đơn giản gắn kết với dịch vụ và gửi tin nhắn MSG_SAY_HELLO cho dịch vụ:

public class ActivityMessenger extends Activity {
    /** Messenger for communicating with the service. */
    Messenger mService = null;

    /** Flag indicating whether we have called bind on the service. */
    boolean mBound;

    /**
     * Class for interacting with the main interface of the service.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = new Messenger(service);
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
            mBound = false;
        }
    };

    public void sayHello(View v) {
        if (!mBound) return;
        // Create and send a message to the service, using a supported 'what' value
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to the service
        bindService(new Intent(this, MessengerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

Để ý rằng ví dụ này không cho biết cách mà dịch vụ có thể phản hồi máy khách. Nếu bạn muốn dịch vụ phản hồi, khi đó bạn cũng cần tạo một Messenger trong máy khách. Sau đó khi máy khách nhận được lệnh gọi lại onServiceConnected(), nó sẽ gửi một Message tới dịch vụ, trong đó bao gồm Messenger của máy khách trong tham số replyTo của phương pháp send().

Bạn có thể xem một ví dụ về cách cung cấp tính năng nhắn tin hai chiều trong MessengerService.java (dịch vụ) và các mẫu MessengerServiceActivities.java (máy khách).

Gắn kết với một Dịch vụ

Các thành phần ứng dụng (máy khách) có thể gắn kết với một dịch vụ bằng cách gọi bindService(). Hệ thống Android khi đó sẽ gọi phương pháp onBind() của dịch vụ, nó trả về một IBinder để tương tác với dịch vụ.

Việc gắn kết diễn ra không đồng bộ. bindService() trả về ngay lập tức và không trả IBinder về máy khách. Để nhận một IBinder, máy khách phải tạo một thực thể của ServiceConnection và chuyển nó cho bindService(). ServiceConnection bao gồm một phương pháp gọi lại mà hệ thống gọi để gửi IBinder.

Lưu ý: Chỉ các hoạt động, dịch vụ, và trình cung cấp nội dung mới có thể gắn kết với một dịch vụ—bạn không thể gắn kết với một dịch vụ từ một hàm nhận quảng bá (broadcast receiver).

Vì vậy, để gắn kết với một dịch vụ từ máy khách của mình, bạn phải:

  1. Triển khai ServiceConnection.

    Việc triển khai của bạn phải khống chế hai phương pháp gọi lại:

    onServiceConnected()
    Hệ thống gọi phương pháp này để gửi IBinder được trả về bởi phương pháp onBind() của dịch vụ.
    onServiceDisconnected()
    Hệ thống Android gọi phương pháp này khi kết nối với dịch vụ bị mất đột ngột, chẳng hạn như khi dịch vụ bị lỗi hoặc bị tắt bỏ. Phương pháp này không được gọi khi máy khách bỏ gắn kết.
  2. Gọi bindService(), chuyển việc triển khai ServiceConnection.
  3. Khi hệ thống gọi phương pháp gọi lại onServiceConnected() của bạn, bạn có thể bắt đầu thực hiện các lệnh gọi tới dịch vụ bằng các phương pháp được định nghĩa bởi giao diện.
  4. Để ngắt kết nối khỏi dịch vụ, hãy gọi unbindService().

    Khi máy khách của bạn bị hủy, nó sẽ bỏ gắn kết khỏi dịch vụ, nhưng bạn nên luôn bỏ gắn kết khi bạn đã tương tác xong với dịch vụ hoặc khi hoạt động của bạn tạm dừng sao cho dịch vụ có thể tắt khi không dùng đến. (Thời điểm phù hợp để gắn kết và bỏ gắn kết được đề cập kỹ hơn ở bên dưới.)

Ví dụ, đoạn mã HTML sau sẽ kết nối máy khách với dịch vụ được tạo bên trên bằng cách mở rộng lớp Trình gắn kết, vì vậy tất cả những việc mà nó phải làm là đổi kiểu IBinder được trả về thành lớp LocalService và yêu cầu thực thể LocalService:

LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
    // Called when the connection with the service is established
    public void onServiceConnected(ComponentName className, IBinder service) {
        // Because we have bound to an explicit
        // service that is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    // Called when the connection with the service disconnects unexpectedly
    public void onServiceDisconnected(ComponentName className) {
        Log.e(TAG, "onServiceDisconnected");
        mBound = false;
    }
};

Với ServiceConnection này, máy khách có thể gắn kết với một dịch vụ bằng cách chuyển nó cho bindService(). Ví dụ:

Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
  • Tham số đầu tiên của bindService() là một Intent trong đó nêu rõ tên của các dịch vụ sẽ gắn kết (mặc dù ý định có thể ngầm hiểu).
  • Tham số thứ hai là đối tượng ServiceConnection.
  • Tham số thứ ba là một cờ cho biết các tùy chọn cho gắn kết. Nên luôn luôn là BIND_AUTO_CREATE để tạo dịch vụ nếu nó chưa hoạt động. Các giá trị có thể khác là BIND_DEBUG_UNBINDBIND_NOT_FOREGROUND, hoặc 0 trong trường hợp không có.

Lưu ý bổ sung

Sau đây là một số lưu ý quan trọng về việc gắn kết với một dịch vụ:

  • Bạn nên luôn bẫy các lỗi ngoại lệ DeadObjectException phát sinh khi kết nối bị đứt. Đây là lỗi ngoại lệ duy nhất phát sinh bởi các phương pháp từ xa.
  • Các đối tượng được xem là tham chiếu khắp các tiến trình.
  • Bạn nên luôn ghép đôi gắn kết và bỏ gắn kết trong khi khớp những khoảnh khắc kết nối và đứt kết nối trong vòng đời của máy khách. Ví dụ:
    • Nếu bạn chỉ cần tương tác với dịch vụ trong khi hoạt động của bạn hiển thị, bạn nên gắn kết trong khi onStart() và bỏ gắn kết trong khi onStop().
    • Nếu bạn muốn hoạt động của mình nhận được phản hồi ngay cả trong khi bị dừng khi đang dưới nền, khi đó bạn có thể gắn kết trong khi onCreate() và bỏ gắn kết trong khi onDestroy(). Chú ý rằng điều này hàm ý rằng hoạt động của bạn cần sử dụng dịch vụ trong toàn bộ thời gian khi nó đang chạy (ngay cả khi chạy ngầm), do đó nếu dịch vụ ở trong một tiến trình khác thì bạn hãy tăng trọng số của tiến trình và khả năng hệ thống tắt bỏ tiến trình đó sẽ cao hơn.

    Lưu ý: Thông thường bạn không nên gắn kết và bỏ gắn kết trong khi onResume()onPause() cho hoạt động của mình, vì những lệnh gọi lại này diễn ra tại mọi thời điểm chuyển tiếp vòng đời và bạn nên duy trì xử lý tại những thời điểm chuyển tiếp này ở mức tối thiểu. Đồng thời, nếu nhiều hoạt động trong ứng dụng của bạn gắn kết với cùng dịch vụ và có sự chuyển tiếp giữa hai trong số những hoạt động đó, dịch vụ có thể bị hủy và tạo lại khi hoạt động hiện tại bỏ gắn kết (trong khi tạm dừng) trước khi hoạt động tiếp theo gắn kết (trong khi tiếp tục). (Sự chuyển tiếp hoạt động này đối với cách mà các hoạt động phối hợp vòng đời của chúng được mô tả trong tài liệu Hoạt động .)

Để biết thêm mã ví dụ, thể hiện cách gắn kết với một dịch vụ, hãy xem lớp RemoteService.java trong ApiDemos.

Quản lý Vòng đời của một Dịch vụ Gắn kết

Khi một dịch vụ bị bỏ gắn kết khỏi tất cả máy khách, hệ thống Android sẽ hủy nó (trừ khi nó cũng được bắt đầu bằng onStartCommand()). Như vậy, bạn không phải quản lý vòng đời dịch vụ của mình nếu nó thuần túy là một dịch vụ gắn kết—hệ thống Android sẽ quản lý nó cho bạn dựa trên việc nó có gắn kết với bất kỳ máy khách nào không.

Tuy nhiên, nếu bạn chọn triển khai phương pháp gọi lại onStartCommand(), vậy thì bạn phải dừng dịch vụ một cách tường minh, vì dịch vụ lúc này đang được coi là được bắt đầu. Trong trường hợp này, dịch vụ sẽ chạy cho tới khi dịch vụ tự dừng bằng stopSelf() hoặc một thành phần khác sẽ gọi stopService(), bất kể nó có gắn kết với bất kỳ máy khách nào không.

Ngoài ra, nếu dịch vụ của bạn được bắt đầu và chấp nhận gắn kết, lúc đó khi hệ thống gọi phương pháp onUnbind() của bạn, bạn có thể tùy chọn trả về true nếu bạn muốn nhận một lệnh gọi tới onRebind() vào lần tới khi một máy khách gắn kết với dịch vụ (thay vì nhận một lệnh gọi tới onBind()). onRebind() sẽ trả về rỗng, nhưng máy khách vẫn nhận được IBinder trong gọi lại onServiceConnected() của mình. Hình 1 bên dưới minh họa lô-gic cho loại vòng đời này.

Hình 1. Vòng đời của một dịch vụ được bắt đầu và cũng cho phép gắn kết.

Để biết thêm thông tin về vòng đời của một dịch vụ được bắt đầu, hãy xem tài liệu Dịch vụ.