How does android use AIDL Service to transmit complex data?
We all know that in Android, data in the Service can be called across processes through AIDL. There are also many instances on the Internet. However, most instances use remote calls for basic data types and seldom involve complex data calls, today, I will use an example to demonstrate how to use AIDL Service to transmit complex data.
Let's start in two steps:
Step 1: deploy our server, that is, the Service:
1: on the Service end, I first define two types: Person and Pet. Because we need to pass the Person object and Pet object across processes, both the Person class and the Pet class must implement the Parcelable interface and define a creater in the implementation class and the Parcelable type. the static Field of the creator.
The Code is as follows:
1 package com.example.remoteservice; 2 3 import android.os.Parcel; 4 import android.os.Parcelable; 5 6 public class Person implements Parcelable { 7 int id; 8 String name; 9 String pass; 10 11 public Person() { 12 13 } 14 15 public Person(int id, String name, String pass) { 16 this.id = id; 17 this.name = name; 18 this.pass = pass; 19 } 20 21 @Override 22 public boolean equals(Object o) { 23 if (this == o) { 24 return true; 25 } 26 if (o == null) { 27 return false; 28 } 29 30 if (getClass() != o.getClass()) { 31 return false; 32 } 33 Person other = (Person) o; 34 35 if (name == null) { 36 if (other.name != null) { 37 return false; 38 } 39 } else if (!name.equals(other.name)) { 40 return false; 41 } 42 43 if (pass == null) { 44 if (other.pass != null) { 45 return false; 46 } 47 } else if (!pass.equals(other.pass)) { 48 return false; 49 } 50 51 return true; 52 } 53 54 @Override 55 public int hashCode() { 56 final int prime = 31; 57 int result = 1; 58 result = prime * result + (name == null ? 0 : name.hashCode()); 59 result = prime * result + (pass == null ? 0 : pass.hashCode()); 60 return result; 61 } 62 63 @Override 64 public int describeContents() { 65 66 return 0; 67 } 68 69 @Override 70 public void writeToParcel(Parcel arg0, int arg1) { 71 arg0.writeInt(id); 72 arg0.writeString(name); 73 arg0.writeString(pass); 74 } 75 76 public static final Parcelable.Creator
CREATOR = new Creator
() { 77 78 @Override 79 public Person createFromParcel(Parcel source) { 80 81 return new Person(source.readInt(), source.readString(), source.readString()); 82 } 83 84 @Override 85 public Person[] newArray(int size) { 86 87 return new Person[size]; 88 } 89 }; 90 91 public int getId() { 92 return id; 93 } 94 95 public void setId(int id) { 96 this.id = id; 97 } 98 99 public String getName() {100 return name;101 }102 103 public void setName(String name) {104 this.name = name;105 }106 107 public String getPass() {108 return pass;109 }110 111 public void setPass(String pass) {112 this.pass = pass;113 }114 115 }
Because we will compare the Person, I overwrite it in the Person class.
Public int hashCode () and public boolean equals (Object o) Methods
1 package com.example.remoteservice; 2 3 import android.os.Parcel; 4 import android.os.Parcelable; 5 6 public class Pet implements Parcelable { 7 String name; 8 float weight; 9 10 public Pet(String name, float weight) {11 this.name = name;12 this.weight = weight;13 }14 15 public String getName() {16 return name;17 }18 19 public void setName(String name) {20 this.name = name;21 }22 23 public float getWeight() {24 return weight;25 }26 27 public void setWeight(float weight) {28 this.weight = weight;29 }30 31 @Override32 public int describeContents() {33 34 return 1;35 }36 37 @Override38 public void writeToParcel(Parcel dest, int flags) {39 dest.writeString(name);40 dest.writeFloat(weight);41 42 }43 44 public static final Parcelable.Creator
CREATOR = new Creator
() {45 46 @Override47 public Pet createFromParcel(Parcel source) {48 49 return new Pet(source.readString(), source.readFloat());50 }51 52 @Override53 public Pet[] newArray(int size) {54 55 return new Pet[size];56 }57 };58 59 @Override60 public String toString() {61 62 return name: + this.name + ;weight: + this.weight;63 }64 65 }
2: After creating custom types, you also need to use AIDL to define them. The code for Person. aidl and Pet. aidl is as follows:
1 package com.example.remoteservice;2 parcelable Person;
1 package com.example.remoteservice;2 parcelable Pet;
3: After completing 1 or 2, you can use AIDL to define the communication interface. Here I define an IPet. aidl interface. The Code is as follows:
1 package com. example. remoteservice; // You must import the package 2 import com. example. remoteservice. person; // specify the position of the custom Class 3 import com. example. remoteservice. pet; 4 5 interface IPet6 {7 List
GetPets (in Person owner); // here, in indicates that the Person object is the input parameter 8}
4: the last step of the server is to implement the Service. Of course, do not forget to register the Service. The Code is as follows:
1 package com. example. remoteservice; 2 3 import com. example. remoteservice. IPet. stub; 4 5 import java. util. arrayList; 6 import java. util. hashMap; 7 import java. util. list; 8 import java. util. map; 9 10 import android. app. service; 11 import android. content. intent; 12 import android. OS. IBinder; 13 import android. OS. remoteException; 14 import android. util. log; 15 16 public class RemoteService extends Service {17 18 private PetBinder petBinder; 19 20 private static Map
> Pets = new HashMap
> (); 21 static {22 ArrayList
List1 = new ArrayList
(); 23 list1.add (new Pet (candy, 2.2f); 24 list1.add (new Pet (sandy, 4.2f); 25 pets. put (new Person (1, sun, sun), list1); 26 27 ArrayList
List2 = new ArrayList
(); 28 list2.add (new Pet (moon, 5.2f); 29 list2.add (new Pet (hony, 6.2f); 30 pets. put (new Person (1, csx, csx), list2); 31 32} 33 34 public class PetBinder extends Stub {// inherit the Stub class in the IPet interface, the Stub class inherits the Binder class, And all PetBinder indirectly inherits the Binder class 35 36 @ Override37 public List
GetPets (Person owner) throws RemoteException {38 39 return pets. get (owner); 40} 41 42} 43 44 @ Override45 public IBinder onBind (Intent intent) {46 47 Log. I (csx, onBind); 48 return petBinder; 49} 50 51 @ Override52 public void onCreate () {53 54 super. onCreate (); 55 Log. I (csx, onCreate); 56 petBinder = new PetBinder (); // instantiate Binder57 58} 59 60 @ Override61 public boolean onUnbind (Intent intent) {62 63 Log. I (csx, onUnbind); 64 return super. onUnbind (intent); 65} 66 67 @ Override68 public void onDestroy () {69 70 super. onDestroy (); 71 Log. I (csx, onDestroy); 72} 73 74}
This is the deployment of my Service (MainActivity does not need to be implemented, because we only provide services and there is no window display ):
Step 2: deploy the client:
1. create a new package on the client. The name must be the same as that of the package where the aidl file is placed on the server. example. remoteservice), and then put the Person. java, Pet. java, Person. aidl, Pet. aidl, IPet. copy aidl to the package
2. Bind a remote service to the activity for data exchange. The layout and activity Code are as follows:
1
10 11
15 16
20 21
27
28 29
35 36 37
41
42 43 44
1 package com. example. remoteclient; 2 3 import android. app. service; 4 import android. content. componentName; 5 import android. content. intent; 6 import android. content. serviceConnection; 7 import android. OS. bundle; 8 import android. OS. IBinder; 9 import android. OS. remoteException; 10 import android. support. v7.app. actionBarActivity; 11 import android. util. log; 12 import android. view. view; 13 import android. view. view. onClickListener; 14 import android. widget. arrayAdapter; 15 import android. widget. button; 16 import android. widget. editText; 17 import android. widget. listView; 18 19 import com. example. remoteservice. IPet; 20 import com. example. remoteservice. person; 21 import com. example. remoteservice. pet; 22 23 import java. util. list; 24 25 public class RemoteClient extends ActionBarActivity {26 27 public static final String REMOTE_SERVICE_ACTION = com. example. remoteservice. remoteService. ACTION; 28 EditText editText; 29 Button button; 30 ListView listView; 31 32 IPet petService; // declare IPet interface 33 List
Pets; 34 ServiceConnection conn = new ServiceConnection () {35 36 @ Override 37 public void onServiceDisconnected (ComponentName name) {38 Log. I (csx, onServiceDisconnected); 39 conn = null; 40} 41 42 @ Override 43 public void onServiceConnected (ComponentName, IBinder service) {44 Log. I (csx, onServiceConnected); 45 petService = IPet. stub. asInterface (service); // implement interface 46 47} 48} through remote service Binder; 49 50 @ Override 51 protected void onCreate (Bundle savedInstanceState) {52 super. onCreate (savedInstanceState); 53 setContentView (R. layout. remote_client_layout); 54 editText = (EditText) findViewById (R. id. editText_person); 55 button = (Button) findViewById (R. id. button_ OK); 56 listView = (ListView) findViewById (R. id. listView_pet); 57 58 Intent service = new Intent (); 59 service. setAction (REMOTE_SERVICE_ACTION); 60 61 bindService (service, conn, Service. BIND_AUTO_CREATE); // bind the remote service 62 63 button. setOnClickListener (new OnClickListener () {64 65 @ Override 66 public void onClick (View v) {67 String personName = editText. getText (). toString (); 68 if (personName = null | personName. equals () {69 70 return; 71} 72 73 try {74 pets = petService. getPets (new Person (1, personName, personName); // call the getPets method of remote service 75 updataListView (); 76 77} catch (RemoteException e) {78 79 e. printStackTrace (); 80} catch (NullPointerException e) {81 e. printStackTrace (); 82} 83 84} 85}); 86 87} 88 89 public void updataListView () {90 listView. setAdapter (null); 91 92 if (pets = null | pets. isEmpty () {93 return; 94 95} 96 ArrayAdapter
Adapter = new ArrayAdapter
(RemoteClient. this, 97 android. r. layout. simple_list_item_1, pets); 98 listView. setAdapter (adapter); 99 100} 101 102 @ Override103 protected void onDestroy () {104 105 unbindService (conn); // unbind 106 super. onDestroy (); 107} 108 109}
So far, all the work has been completed. Let's take a look at the effect below: I enter "csx" in the editing box, and click "OK". The corresponding pets data in the RemoteService on the server will be displayed.