效果图如下:
点击 绑定--->调用服务中的方法 结果为:
步骤如下:
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.csdn.net/download/qq_33363534/9475455