除了上一篇文章我们提到的通过service提供音乐播放等类似的服务之外,我们还可以通过service将对象传递回来哦,你知道怎么用吗,先看例子:
当我们点击“获取”时,会从另一个线程的service中获取一个对象,然后将里面的内容读出来。
--------------------------------------------------------------------------------------------
对于aidl实现以对象的方式交互。主要步骤如下:
服务端:
第一:定义一个实体类,这里是Beauty,定义一个服务接口aidl文件RemoteBeauty.aidl,这里有一点需要注意,我们引用自定义的实体类到aidl中时需要通过import导入包,但是你会发现,即使你导入了包,还是提示找不到,这时候,你要做的是,建一个以实体类名称命名的aidl文件,如Beauty.aidl,在里面添加一句pracelable Beauty。
第二:开始编写Beauty,这里一定要注意,它一定要实现Pracelable接口,该接口是一个序列化的接口,功能和serializable相似,但是功能更加的迅速。此外,在该Beauty内部一定要声明一个public static final Pracelable.Creator<T>CREATOR对象!!除了里面的那个T代表实体类之外,其他的都不准改变哦。
第三:在androidManifest.xml中注册service。并定义好访问该service的action字符串。
客户端:
客户端这边相应的要简单很多,但是要注意的一点是,要将实体类还有aidl文件都拷贝过来哦,而且要保证路径完全一致!!
-------------------------------------------------------------
代码示例:
服务端:
Beauty.java
- package cn.com.chenzheng_java.service;
- import android.os.Parcel;
- import android.os.Parcelable;
- /**
- *
- * @author chenzheng_java
- * @description Parcelable是android提供的一个比serializable效率更高的序列号接口
- * 这里必须要继承Parcelable哦,不序列号怎么可以传递……对吧?!
- * 在实体类我们要做两件重要的事情:
- * 第一:实现Parcelable接口
- * 第二:定义一个Parcelable.Creator类型的CREATOR对象
- * 第三:要提供一个Beauty.aidl文件,其中内容为parcelable Beauty,定义了之后,在其他aidl文件中引用Beauty时便不会提示出错了。
- * @since 2011/03/18
- *
- */
- public class Beauty implements Parcelable {
- String name ;
- int age ;
- String sex ;
- 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 String getSex() {
- return sex;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- @Override
- public int describeContents() {
- return 0;
- }
- /**
- * 将对象序列号
- * dest 就是对象即将写入的目的对象
- * flags 有关对象序列号的方式的标识
- * 这里要注意,写入的顺序要和在createFromParcel方法中读出的顺序完全相同。例如这里先写入的为name,
- * 那么在createFromParcel就要先读name
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeInt(age);
- dest.writeString(sex);
- }
- /**
- * 在想要进行序列号传递的实体类内部一定要声明该常量。常量名只能是CREATOR,类型也必须是
- * Parcelable.Creator<T>
- */
- public static final Parcelable.Creator<Beauty> CREATOR = new Creator<Beauty>() {
- /**
- * 创建一个要序列号的实体类的数组,数组中存储的都设置为null
- */
- @Override
- public Beauty[] newArray(int size) {
- return new Beauty[size];
- }
- /***
- * 根据序列号的Parcel对象,反序列号为原本的实体对象
- * 读出顺序要和writeToParcel的写入顺序相同
- */
- @Override
- public Beauty createFromParcel(Parcel source) {
- String name = source.readString();
- int age = source.readInt();
- String sex = source.readString();
- Beauty beauty = new Beauty();
- beauty.setName(name);
- beauty.setAge(age);
- beauty.setSex(sex);
- return beauty;
- }
- };
- }
RemoteService.java
- package cn.com.chenzheng_java.service;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- /**
- *
- * @author chenzheng_java
- * @description 提供服务的service
- *
- */
- public class RemoteService extends Service {
- @Override
- public IBinder onBind(Intent intent) {
- Log.i("通知", "执行了OnBind");
- return new MyBinder();
- }
- private class MyBinder extends RemoteBeauty.Stub{
- @Override
- public Beauty getBeauty() throws RemoteException {
- Beauty beauty = new Beauty();
- beauty.setName("feifei");
- beauty.setAge(21);
- beauty.setSex("female");
- return beauty;
- }}
- }
ServiceActivity.java
- package cn.com.chenzheng_java.service;
- import android.app.Activity;
- import android.os.Bundle;
- /**
- * @description 进程之间对象数据的传递
- * @author chenzheng_java
- *
- */
- public class ServiceActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- }
Beauty.aidl
- parcelable Beauty;
RemoteBeauty.aidl
- package cn.com.chenzheng_java.service;
- import cn.com.chenzheng_java.service.Beauty;
- interface RemoteBeauty {
- Beauty getBeauty();
- }
manifest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="cn.com.chenzheng_java.service"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="8" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".ServiceActivity"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <!-- service开始 -->
- <service android:name="RemoteService">
- <intent-filter>
- <action android:name="cn.com.chenzheng_java.remote2"/>
- </intent-filter>
- </service>
- <!-- service结束 -->
- </application>
- </manifest>
-------------------------------------
客户端:
ClientActivity.java
- package cn.com.chenzheng_java.client;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
- import cn.com.chenzheng_java.service.Beauty;
- import cn.com.chenzheng_java.service.RemoteBeauty;
- public class ClientActivity extends Activity implements OnClickListener {
- TextView textView ;
- Button button ;
- String actionName = "cn.com.chenzheng_java.remote2";
- RemoteBeauty remoteBeauty;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- textView = (TextView) findViewById(R.id.textView1);
- button = (Button) findViewById(R.id.button1);
- button.setOnClickListener(this);
- }
- private class MyServiceConnection implements ServiceConnection{
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Log.i("通知", "链接成功!");
- remoteBeauty = RemoteBeauty.Stub.asInterface(service);
- try {
- Beauty beauty = remoteBeauty.getBeauty();
- textView.setText("美女 姓名:"+beauty.getName()+" 年龄:"+beauty.getAge() +" 性别:"+beauty.getSex());
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- }
- MyServiceConnection connection = new MyServiceConnection();
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(actionName);
- bindService(intent, connection, Context.BIND_AUTO_CREATE);
- }
- }
另外Beauty.java 以及RemoteBeauty.aidl都是从服务端系统中拷贝过来的哦。
如果你想你的service在系统开机时自启动。可以在service的androidManifest.xml中加上这样的配置。
<receiver android:name=".StartBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>