原理图:
1、访问远程服务的原理图
2、AIDL介绍
3、IPC原理图
二、实现步骤
上面的操作(之前的那一篇博客)是一个本地的服务。在开发的时候有可能还会去调用别人应用里面提供好的服务。
远程绑定服务,调用服务里面的方法。
1 编写一个接口,再把接口文件修改为aidl,不能有修饰符。
如果我们使用了自定义对象需要实现Parcelable接口,还需要定义个一个aidl文件对这个类进行一个描述(Student.aidl).
编译器就会在gen目录下面生成对应的xx.java文件
2 在服务里面创建一个内部类:extends Stub 实现未实现的方法。
生成这个类的对象通过onBind()方法返回。
3 在客户端绑定服务。
注意:
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
ibinder = Stub.asInterface(service);
}
三、代码如下:
1、client端
1)main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="学号" /> <EditText android:id="@+id/et_no" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="查询1" android:onClick="query1" /> <TextView android:id="@+id/tv_info" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
2)MainActivity
package com.njupt.client1; import com.njupt.domain.Student; import com.njupt.inter.IStudentQueryService; import com.njupt.inter.IStudentQueryService.Stub; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.view.Menu; import android.view.View; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { private EditText et_no; private TextView tv_info; private MyServiceConnection conn; private IStudentQueryService ibinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); et_no = (EditText) findViewById(R.id.et_no); tv_info = (TextView) findViewById(R.id.tv_info); conn = new MyServiceConnection(); Intent intent = new Intent(); intent.setAction("com.njupt.action.myservice"); bindService(intent,conn,BIND_AUTO_CREATE); } private class MyServiceConnection implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { ibinder = Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { ibinder = null; conn = null; } } @Override protected void onDestroy() { super.onDestroy(); unbindService(conn); } public void query1(View v)throws RemoteException{ String no = et_no.getText().toString(); Student student = ibinder.queryStudent(Integer.parseInt(no)); tv_info.setText(student.toString()); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
2、server端
这里,server端不需要创建Activity文件
1)MyService
package com.njupt.service; import com.njupt.domain.Student; import com.njupt.inter.IStudentQueryService.Stub; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyService extends Service { private StudentBinder ibinder = new StudentBinder(); private Student[] students = new Student[]{ new Student(1,"刘亦菲",25), new Student(2,"章泽天",21), new Student(3,"allen",21), new Student(4,"刘诗诗",25) }; @Override public IBinder onBind(Intent intent) { return ibinder; } private class StudentBinder extends Stub{ public Student queryStudent(int no){ return query(no); } } private Student query(int no){ return students[no - 1]; } }
2)IStudentQueryService
package com.njupt.inter; import com.njupt.domain.Student; interface IStudentQueryService { Student queryStudent(int no); }
3)Student
package com.njupt.domain; import android.os.Parcel; import android.os.Parcelable; public class Student implements Parcelable { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } 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; } public Student(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } public Student() { super(); } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", age=" + age + "]"; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(id); dest.writeString(name); dest.writeInt(age); } public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>() { public Student createFromParcel(Parcel in) { return new Student(in); } public Student[] newArray(int size) { return new Student[size]; } }; private Student(Parcel in) { id = in.readInt(); name = in.readString(); age = in.readInt(); } }
4)创建一个Student.aidl文件,并在里面写上以下代码:
package com.njupt.domain; parcelable Student;
并将IStudentQueryService.java文件的后缀名改成.aidl
5)将.aidl文件所在的包由Server端拷一份到Client端
6)AndroidManifest.xml
在清单文件上注册service组件,并暴露服务的接口
<service android:name="com.njupt.service.MyService"> <intent-filter > <action android:name="com.njupt.action.myservice"/> </intent-filter> </service>