效果图如下:
点击 绑定--->调用服务中的方法 结果为:
步骤如下:
1. 自定义服务 MyService ,在服务中定义几个自己需要的方法,如:(start() , pause()等);
2. 如果方法中需要自定义的类型,则让该类型序列化(使用Parcelable 序列化, Seriable不可以),要实现对应的方法打包:
writeToParcel(Parcel dest, int flags)
然后解包:注意打包和解包的写入和读取顺序要一致:
Creator<Student> = Creator<Student>() {
Student createFromParcel(Parcel in) {
id = in.readInt();String name = in.readString();Student(id, name);}
Student[] newArray(size) {
Student[size];}
};
3. 创建和自定义类的名称相同的 .aidl 文件 ,如自定义了Student类,序列化Person后要创建Student.aidl文件:
package com.hong.servicetest;//包名;
parcelable Student;//序列
4. 创建aidl文件(IMyService):
package com.hong.servicetest;
import com.hong.servicetest.Student;//自定义的类要倒包;不然报错
interface IMyService {
//要代理的几个方法;当然也可以不全把服务中的方法写进来,需要哪个方法就写哪个方法;
void start();
void pause();
。。。。。。
Student getStudent();
}
5. 此时 rebuild 一下,没有错误的话会在如下文件里生成 aidl 文件, 如果有错误根据报错内容慢慢改即可:
6. 在MyService中的onBind()方法中返回代理对象:
IBinder onBind(Intent intent) {
;
}
在代理中调用相应的方法 或写入相应的逻辑:
IMyService.Stub = IMyService.Stub() {
MyService = MyService.;start() RemoteException {
.start();}
pause() RemoteException {
.pause();
}
。。。。。。
Student getStudent() {
Student student = .getStudent();
student;
}
};
7. 在activity中写好绑定服务的逻辑代码,在ServiceConnection中的重写方法中加入:
IMyService aidlService;
aidlService = IMyService.Stub.asInterface(service);//初始化 IMyService,以便调用当中的方法;
这样就可以使用代理接口中所提供的方法了;
8. 退出时解绑
==========================无聊的分割线=================================
代码详情:
先写一个aidl文件:
服务MyService中的代码:
package com.hong.servicetest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* Created by Hong on 2016/3/28.
*/
public class MyService extends Service {
private static final String TAG = MyService.class.getSimpleName();
private Student student;
/**
* 设置代理
*/
private IMyService.Stub mIBinder = new IMyService.Stub() {
MyService service = MyService.this;//获取服务对象
@Override
public void start() throws RemoteException {
service.start();//调用服务中的方法; 以下类似;
}
@Override
public void pause() throws RemoteException {
service.pause();
}
@Override
public void stop() throws RemoteException {
service.stop();
}
@Override
public void show() throws RemoteException {
service.show();
}
@Override
public String getString() throws RemoteException {
return "a";
}
public Student getStudent() {
Student student = service.getStudent();
return student;
}
};
@Override
public void onCreate() {
super.onCreate();
student = new Student(1, "Tom");
}
/**
* 返回代理对象
*
* @param intent
* @return
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mIBinder;
}
public void start() {
Log.e(TAG, "start: ");
}
public void pause() {
Log.e(TAG, "pause: ");
}
public void stop() {
Log.e(TAG, "stop: ");
}
public void show() {
Log.e(TAG, "show: ");
}
/**
* 获取 Student 对象, Studen 类一定要进行 Parcelable ;自定义的类型也要写一个Student.aidl文件,否则报错;
* @return
*/
public Student getStudent() {
return student;
}
public String getString() {
return "a";
}
}
Bean(Student)中的代码:
package com.hong.servicetest;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by Hong on 2016/3/28.
*/
public class Student implements Parcelable{//实现Parcelable
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
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;
}
@Override//没用
public int describeContents() {
return 0;
}
@Override//把数据打包
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
}
/**
* 要重写Creator<Student> 里面的方法
*/
public static final Creator<Student> CREATOR = new Creator<Student>() {
@Override//从parcel中解析包中的数据,注意:一定要按打包的顺序解包!
public Student createFromParcel(Parcel in) {
int id = in.readInt();//打包时候第一个就是id
String name = in.readString();//打包时候第二个是name,所以先解包id,再解包name;
return new Student(id, name);//最后把数据返回到student对象中;
}
@Override
public Student[] newArray(int size) {
return new Student[size];//这一步很简单把size放进去就行
}
};
}
Student.aidl 中的代码:就两行:
com.hong.servicetest;
parcelable Student;
MainActivity中的代码:
package com.hong.servicetest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
EditText et_id;
EditText et_name;
private ServiceConnection conn;
IMyService aidlService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_id = (EditText) findViewById(R.id.tv_id);
et_name = (EditText) findViewById(R.id.et_name);
}
/**
* 绑定服务
* @param view
*/
public void bind(View view) {
if (conn == null) {
Intent intent = new Intent("com.hong.servicetest.MyService.INTENT");
conn = new ServiceConnection() {
@Override//连接时调用
public void onServiceConnected(ComponentName name, IBinder service) {
aidlService = IMyService.Stub.asInterface(service);//初始化 IMyService,以便调用当中的方法;
try {
aidlService.start();//调用了IMyService的方法;
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
aidlService = null;//断开连接时调用, 把aidlService置空;
}
};
bindService(intent, conn, Context.BIND_AUTO_CREATE);
Toast.makeText(this, "绑定", Toast.LENGTH_SHORT).show();
}
}
/**
* 调用服务中的方法
* @param v
* @throws RemoteException
*/
public void showMethod(View v) throws RemoteException {
if (aidlService != null) {
Student student = aidlService.getStudent();//调用服务中的方法获取student对象;
int id = student.getId();
String name = student.getName();
et_id.setText(""+id);//设置到et_id控件中;
et_name.setText(name);//设置到et_name中;
}else {
Toast.makeText(this, "还未绑定", Toast.LENGTH_SHORT).show();
}
}
/**
* 解绑服务
* @param v
*/
public void unBind(View v) {
if (conn != null) {
unbindService(conn);
conn = null;
Toast.makeText(this, "解绑", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "还未绑定", Toast.LENGTH_SHORT).show();
}
}
/**
* 退出时解绑服务
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (conn != null) {
unbindService(conn);
conn = null;
Toast.makeText(this, "解绑", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "还未绑定", Toast.LENGTH_SHORT).show();
}
}
}
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10sp"
android:text="TestBindService"
android:textSize="28sp" />
<Button
android:onClick="bind"
android:text="绑定"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:onClick="unBind"
android:text="解绑"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:onClick="showMethod"
android:text="调用服务中的方法"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<EditText
android:hint="id"
android:id="@+id/tv_id"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<EditText
android:hint="name"
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
最后下载链接:
http://download.youkuaiyun.com/download/qq_33363534/9475455