1. 程式人生 > >Android 中的 IPC 方式一:使用 Bundle

Android 中的 IPC 方式一:使用 Bundle

前言

Android 中跨程序通訊的方式比較多,比如可以通過在 Intent 中附加 extras 來傳遞資訊,或者通過共享檔案的方式來共享資料,還可以採用 Binder 方式來跨程序通訊,另外,ContentProvider 天生就是支援跨程序訪問的,因此我們也可以採用它來進行 IPC。此外,通過網路通訊也是可以實現資料傳遞的,所以 Socket 也是可以實現 IPC 的。今天我們先來介紹一下通過使用 Bundle 的方式進行 IPC。

使用 Bundle

我們知道四大元件中的三大元件(Activity、Service、BroadcastReceiver)都是支援在 Intent 中傳遞 Bundle 資料的,由於 Bundle 實現了 Parcelable 介面,所以它可以方便地在不同的程序間傳輸。

基於這一點,當我們在一個程序中啟動了另一個程序的 Activity、Service 和 Receiver,我們就可以在 Bundle 中附加我們需要傳輸給遠端程序的資訊並通過 Intent 傳送出去。當然,我們傳輸的資料必須能夠被序列化,比如基本型別、實現了 Parcelable 介面的物件、實現了 Serializable 介面的物件以及一些 Android 支援的特殊物件。

A 程序中 MainActivity:

Intent intent = new Intent();
intent.setClass(MainActivity.this, SecondActivity.class
); User user = new User(0, "jake"); intent.putExtra("extra_user", (Serializable) user); startActivity(intent);

B 程序中 SecondActivity:

@Override
protected void onResume() {
    super.onResume();
    User user = (User) getIntent().getSerializableExtra("extra_user");
    Log.d(TAG, "user:" + user.toString());
}

其中 User 類:

public class User implements Serializable {
    private static final long serialVersionUID = 519067123721295773L;
    public int userId;
    public String userName;

    public User() {
    }

    public User(int userId, String userName) {
        this.userId = userId;
        this.userName = userName;
    }

    @Override
    public String toString() {
        return String.format(
                "User:{userId:%s, userName:%s}",userId, userName);
    }

}

Bundle 不支援的型別無法通過它在程序間傳遞。

除了直接傳遞資料這種典型的使用場景,它還有一種特殊的使用場景。比如 A 程序正在進行一個計算,計算完成後它要啟動 B 程序的一個元件並把計算結果傳遞給 B 程序,可是遺憾的是這個計算結果不支援放入到 Bundle 中,因此無法通過 Intent 來傳輸,這個時候如果我們使用其他的 IPC 方式就會略顯複雜。

可以考慮如下方式:

我們通過 Intent 啟動 B 的一個 Service 元件(比如 IntentService),讓 Service 在後臺進行計算,計算完畢後再啟動 B 程序中真正要啟動的目標元件,由於 Service 也執行在 B 程序中,所以目標元件就可以直接獲取計算記過,這樣一來就輕鬆解決了跨程序的問題。這種方式的核心思想在於將原本需要在 A 程序的計算任務轉移到 B 程序的後臺 Service 中去執行,這樣就成功地避免了程序間通訊問題,而且只用了很小的代價。