android使用遠程服務要實現的Parcelable和相應的aidl文件



如果在項目中用到aidl,而aidl中的對象類型又用到了自定義的對象等不適java中的類型(可能不一定非要是java中的類型,反正就是aidl不接受的類型)

就會報錯解決辦法是讓這個類型實現Parcelable具體用法在下方。

說一下使用aidl用這個對象的注意事項:


1.aidl文件要import對象所在的包

package com.xxxx.xxxx.download;
import com.xxxx.xxxx.xxxx.Ring;
interface IDownloadService {
	
	void startManage();
	
	void addTask(in Ring ring);
	
	void pauseTask(String url);
	
	void deleteTask(String url);
	
	void continueTask(String url);
}

2.對象所在的包要有針對對象的aidl文件

package com.xxxx.xxxx.modes;
parcelable  Ring;

3.還要說明的是aidl使用對象時要說明是引用還是輸出(可能是這個意思),否則會報

xx can be an out parameter, so you must declare it as in, out or inout.

所以

void addTask(in Ring ring);

裏面有一個 in,

同理如果是輸出,就用out;如果是輸入輸出,就用in

原因是aidl文件沒有那麼智能,只是一個指向映射關係



  



1. Parcelable接口


Interface for classes whose instances can be written to and restored from a Parcel。 Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface。


2.實現Parcelable就是爲了進行序列化,那麼,爲什麼要序列化?


1)永久性保存對象,保存對象的字節序列到本地文件中;


2)通過序列化對象在網絡中傳遞對象;


3)通過序列化在進程間傳遞對象。


3.實現序列化的方法


Android中實現序列化有兩個選擇:一是實現Serializable接口(是JavaSE本身就支持的),一是實現Parcelable接口(是Android特有功能,效率比實現Serializable接口高效,可用於Intent數據傳遞,也可以用於進程間通信(IPC))。實現Serializable接口非常簡單,聲明一下就可以了,而實現Parcelable接口稍微複雜一些,但效率更高,推薦用這種方法提高性能。


注:Android中Intent傳遞對象有兩種方法:一是Bundle.putSerializable(Key,Object),另一種是Bundle.putParcelable(Key,Object)。當然這些Object是有一定的條件的,前者是實現了Serializable接口,而後者是實現了Parcelable接口。


4.選擇序列化方法的原則


1)在使用內存的時候,Parcelable比Serializable性能高,所以推薦使用Parcelable。


2)Serializable在序列化的時候會產生大量的臨時變量,從而引起頻繁的GC。


3)Parcelable不能使用在要將數據存儲在磁盤上的情況,因爲Parcelable不能很好的保證數據的持續性在外界有變化的情況下。儘管Serializable效率低點,但此時還是建議使用Serializable 。


5.應用場景


需要在多個部件(Activity或Service)之間通過Intent傳遞一些數據,簡單類型(如:數字、字符串)的可以直接放入Intent。複雜類型必須實現Parcelable接口。


6、Parcelable接口定義


複製代碼
public interface Parcelable 
{
    //內容描述接口,基本不用管
    public int describeContents();
    //寫入接口函數,打包
    public void writeToParcel(Parcel dest, int flags);
    //讀取接口,目的是要從Parcel中構造一個實現了Parcelable的類的實例處理。因爲實現類在這裏還是不可知的,所以需要用到模板的方式,繼承類名通過模板參數傳入
    //爲了能夠實現模板參數的傳入,這裏定義Creator嵌入接口,內含兩個接口函數分別返回單個和多個繼承類實例
    public interface Creator<T> 
    {
           public T createFromParcel(Parcel source);
           public T[] newArray(int size);
    }
}
複製代碼
7、實現Parcelable步驟


1)implements Parcelable


2)重寫writeToParcel方法,將你的對象序列化爲一個Parcel對象,即:將類的數據寫入外部提供的Parcel中,打包需要傳遞的數據到Parcel容器保存,以便從 Parcel容器獲取數據


3)重寫describeContents方法,內容接口描述,默認返回0就可以


4)實例化靜態內部對象CREATOR實現接口Parcelable.Creator


public static final Parcelable.Creator<T> CREATOR
注:其中public static final一個都不能少,內部對象CREATOR的名稱也不能改變,必須全部大寫。需重寫本接口中的兩個方法:createFromParcel(Parcel in) 實現從Parcel容器中讀取傳遞數據值,封裝成Parcelable對象返回邏輯層,newArray(int size) 創建一個類型爲T,長度爲size的數組,僅一句話即可(return new T[size]),供外部類反序列化本類數組使用。


簡而言之:通過writeToParcel將你的對象映射成Parcel對象,再通過createFromParcel將Parcel對象映射成你的對象。也可以將Parcel看成是一個流,通過writeToParcel把對象寫到流裏面,在通過createFromParcel從流裏讀取對象,只不過這個過程需要你來實現,因此寫的順序和讀的順序必須一致。


代碼如下:


複製代碼
public class MyParcelable implements Parcelable 
{
     private int mData;


     public int describeContents() 
     {
         return 0;
     }


     public void writeToParcel(Parcel out, int flags) 
     {
         out.writeInt(mData);
     }


     public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() 
     {
         public MyParcelable createFromParcel(Parcel in) 
         {
             return new MyParcelable(in);
         }


         public MyParcelable[] newArray(int size) 
         {
             return new MyParcelable[size];
         }
     };
     
     private MyParcelable(Parcel in) 
     {
         mData = in.readInt();
     }
 }
複製代碼
8、Serializable實現與Parcelabel實現的區別


1)Serializable的實現,只需要implements  Serializable 即可。這只是給對象打了一個標記,系統會自動將其序列化。


2)Parcelabel的實現,不僅需要implements  Parcelabel,還需要在類中添加一個靜態成員變量CREATOR,這個變量需要實現 Parcelable.Creator 接口。


兩者代碼比較:


1)創建Person類,實現Serializable


複製代碼
public class Person implements Serializable
{
    private static final long serialVersionUID = -7060210544600464481L;
    private String name;
    private int age;
    
    public String getName()
    {
        return name;
    }
    
    public void setName(String name)
    {
        this.name = name;
    }
    
    public int getAge()
    {
        return age;
    }
    
    public void setAge(int age)
    {
        this.age = age;
    }
}
複製代碼
2)創建Book類,實現Parcelable


複製代碼
public class Book implements Parcelable
{
    private String bookName;
    private String author;
    private int publishDate;
    
    public Book()
    {
        
    }
    
    public String getBookName()
    {
        return bookName;
    }
    
    public void setBookName(String bookName)
    {
        this.bookName = bookName;
    }
    
    public String getAuthor()
    {
        return author;
    }
    
    public void setAuthor(String author)
    {
        this.author = author;
    }
    
    public int getPublishDate()
    {
        return publishDate;
    }
    
    public void setPublishDate(int publishDate)
    {
        this.publishDate = publishDate;
    }
    
    @Override
    public int describeContents()
    {
        return 0;
    }
    
    @Override
    public void writeToParcel(Parcel out, int flags)
    {
        out.writeString(bookName);
        out.writeString(author);
        out.writeInt(publishDate);
    }
    
    public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>()
    {
        @Override
        public Book[] newArray(int size)
        {
            return new Book[size];
        }
        
        @Override
        public Book createFromParcel(Parcel in)
        {
            return new Book(in);
        }
    };
    
    public Book(Parcel in)
    {
        bookName = in.readString();
        author = in.readString();
        publishDate = in.readInt();
    }

}

如果用到了boolean類型,可以這樣解決

writeToParcel:  
  
dest.writeByte((byte) (myBoolean ? 1 : 0));     //if myBoolean == true, byte == 1  
readFromParcel:  
  
myBoolean = in.readByte() != 0;     //myBoolean == true if byte != 0  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章