原理图:
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>