Android間的進程通訊(傳遞複雜物件)

來源:互聯網
上載者:User

標籤:android   des   style   blog   class   code   

Android間的進程通訊(傳遞複雜物件)完成對複雜物件的序列化

在Android中傳遞複雜資料類型的時候要通過將序列化,在Android中提供了一個介面Parcelable來實現對對象的序列化。

下面對需要傳輸的對象進行序列化操作,首先看自訂的類Person。

package com.example.service_parcelable_conmmute.bean;import android.graphics.Bitmap;/** * 用來傳輸的對象結構 * @author Xinyuyu * */public class Person {    private String name;    private String age;    private Bitmap figure;        public Person(){            }    public Person(String name, String age, Bitmap figure){        this.name = name;        this.age = age;        this.figure =figure;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getAge() {        return age;    }    public void setAge(String age) {        this.age = age;    }    public Bitmap getFigure() {        return figure;    }    public void setFigure(Bitmap figure) {        this.figure = figure;    }}

這個類就是一般的JavaBean包含了一些get/set方法,我們要做的就是在進程之間傳遞該對象的值。所以就要將該對象進行序列化,下面實現一個類來完成該任務。

建立ParcelablePerson類,來完成對Person的序列化和還原序列化的操作。其代碼如下:

public class ParcelablePerson implements Parcelable {    Person person = new Person();        public Person getPerson() {        return person;    }    public void setPerson(Person person) {        this.person = person;    }    public ParcelablePerson(Person person){        this.person = person;    }    public ParcelablePerson(Parcel source){        person.setName(source.readString());        person.setAge(source.readString());        person.setFigure((Bitmap)source.readParcelable(Bitmap.class.getClassLoader()));    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeString(person.getName());        dest.writeString(person.getAge());        dest.writeParcelable(person.getFigure(), PARCELABLE_WRITE_RETURN_VALUE);    }        public static final Parcelable.Creator<ParcelablePerson> CREATOR = new Parcelable.Creator<ParcelablePerson>(){        @Override        public ParcelablePerson createFromParcel(Parcel source) {            return new ParcelablePerson(source);        }        @Override        public ParcelablePerson[] newArray(int size) {            return new ParcelablePerson[size];        }    };}

這段代碼中完成了對Person對象的序列化與還原序列化,實現Parcelable介面要做的就是來重寫幾個方法(分別完成序列化和還原序列化),writeToParcel(Parcel dest, int flags)完成的就是對對象的序列化

其中的參數Parcel是一個容器,將對象放入其中就是序列化的過程。而CREATOR中的createFormParcel(Parcel source)來完成的就是還原序列化,可以返回一個複雜的對象。實現了這寫,就完成了對複雜物件的序列化和還原序列化操作,這樣我們就可以對它進行傳輸了。

完成綁定服務,完成進程中的通訊

以上我們只是完成了對一個複雜物件的序列化,下面我們要做的是建立服務,並且完成傳輸。

首先我們要做的是建立一個服務,在Android中建立一個服務要做的就是去實現Service介面。下面是發送對象的一個服務代碼

public class ServiceForSendObject extends Service {    private static final String MSG = "MESSAGE";    private ParcelablePerson parcelablePerson;    private Person person;    // =====================================    SendObject.Stub sendBinder = new Stub(){        @Override        public ParcelablePerson getPersonInfo() throws RemoteException {            Log.i(MSG, "調用getPersonInfo()介面實現,返回一個序列化的對象");            return parcelablePerson;        }};    // =====================================        @Override    public void onCreate() {        person = new Person("xinyuyu", "25", BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.ic_launcher)));        parcelablePerson = new ParcelablePerson(person);        super.onCreate();        Log.i(MSG, "回調onCreate()建立服務");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.i(MSG, "回調onStartCommand()啟動服務");        return super.onStartCommand(intent, flags, startId);    }    @Override    public boolean onUnbind(Intent intent) {        Log.i(MSG, "回調onUnbind解除綁定服務");        return super.onUnbind(intent);    }    @Override    public void onDestroy() {        Log.i(MSG, "回調onDestroy銷毀服務");        super.onDestroy();    }    @Override    public IBinder onBind(Intent intent) {        Log.i(MSG, "回調onBind()方法綁定服務");        return sendBinder;    }}

在該段代碼中輸出各個階段的一些資訊,關鍵是在onCreat()方法中完成執行個體化一個對象,並且對該對象完成序列化操作。在分割線之間的代碼是關鍵代碼,注意在IBinder()中返回的是一個SendObject.Stub對象。而這個類是如何產生的呢?我們在完成進程間傳輸的時候需要用到Android中的AIDL語言來定義一個介面,下面我們來建立一個名為SendObject的aidl檔案,SendObject.aidl

package com.example.service_parcelable_conmmute_service.aidl;import com.example.service_parcelable_conmmute.bean.ParcelablePerson;interface SendObject {    ParcelablePerson getPersonInfo();}

這個介面中的import會報錯,這時候需要在建立一個AIDL檔案,將其名字設定為和序列化類別一樣,這裡就起做ParcelablePerson.aidl。其內容如下

package com.example.service_parcelable_conmmute.bean;

parcelable ParcelablePerson;

完成這些就不會有錯誤了。

這時候你會發現在gen目錄下有一個和你的aidl名字一樣Java檔案即SendObject.java。而我們使用的SendObject.Stub就在其中。開啟這個檔案看一下,你會發現SendObject.Stub是這樣一個類,實現了SendObject介面並且繼承了android.os.Binder類。這樣我們就重寫SendObject方法,將其實現功能。就是分割線直接的代碼。

public static abstract class Stub extends android.os.Binder implements com.example.service_parcelable_conmmute_service.aidl.SendObject

還要注意一點進程間的服務通訊應該更改AndroidManifest.xml檔案的屬性,如下

<service android:name="com.example.service_parcelable_conmmute.service.ServiceForSendObject"android:process=":remote"><intent-filter>        <action android:name="com.example.service_parcelable_conmmute.service.SEND_OBJECT"/>            <category android:name="android.intent.category.DEFAULT" />    </intent-filter></service>

這樣可以完成隱式的傳遞Intent。完成了這些,服務端就完成了。這個時候可以運行下代碼。

啟動介面

點擊初始化服務後,可以看到服務開始運行

紅色框中為我們的服務。

點擊兩按鈕後LogCat輸出的資訊

從中可以看出來這個服務的生命週期。

以上我們就完成了服務端的工作了,下面來進行用戶端的完成。

在用戶端我們首先需要的是將服務端寫好的那些AIDL檔案和實體類拷貝到該工程下(連同包名進行拷貝)如

然後我們所要完成的就是完成用戶端的activity程式了。將倆個程式進行聯絡的就是我們的SendObject介面。看下面代碼

public class A extends Activity {        private Button show_button;    private TextView show_name_age;    private ImageView show_image;    private Button unbind_ser;    private SendObject sendObject;    private ParcelablePerson parcelablePerson;    private Person person;    private ServiceConnection connection = new ServiceConnection(){                // 建立綁定後service程式調用onBind()方法,返回一個IBinder對象        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            sendObject = SendObject.Stub.asInterface(service);                try {                parcelablePerson = sendObject.getPersonInfo();                person = parcelablePerson.getPerson();                Log.i("", person.getName());                    show_name_age.setText(person.getName() + "\n" + person.getAge());                show_image.setImageBitmap(person.getFigure());                            } catch (RemoteException e) {                e.printStackTrace();            }        }        @Override        public void onServiceDisconnected(ComponentName name) {            Log.i("", "error");                    }    };    @Override    protected void onCreate(Bundle savedInstanceState) {                        super.onCreate(savedInstanceState);        setContentView(R.layout.a);        show_button = (Button)this.findViewById(R.id.button1);        show_name_age = (TextView)this.findViewById(R.id.textView1);        show_image = (ImageView)this.findViewById(R.id.imageView1);        unbind_ser = (Button)this.findViewById(R.id.button2);                show_button.setOnClickListener(new OnClickListener(){            @Override            public void onClick(View v) {                // 隱式傳遞intent                Intent intent = new Intent();                intent.setAction("com.example.service_parcelable_conmmute.service.SEND_OBJECT");                bindService(intent, connection, BIND_AUTO_CREATE);            }});        // 解除綁定(服務會在activity銷毀後自動銷毀)        unbind_ser.setOnClickListener(new OnClickListener(){            @Override            public void onClick(View v) {                unbindService(connection);              }                    });    }}

將該程式與服務進行綁定就用到了bindService()方法,看該方法中的參數,第一個是一個intent,第二個是一個ServiceConnection類,與服務建立串連,接收到onBind()傳輸的資料。從這個方法中我們就得到了傳遞過來的對象。運行用戶端程式

點擊第一個按鈕後會顯示出來一個Person對象的資訊。這就說明資料從服務端傳輸了過來。

LogCat輸出的資訊

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.