android AIDL实现进程间的通信

android service作为四大组件之一,实现进程通讯,以及相关的服务。以一个简单的实例为主。
目的:掌握service+adil的简单通讯。
实例要求:编写两个程序,使用AIDL实现远程服务通信。一个作为服务器,一个作为客服端,服务器端提供数据,数据对象为自定义的person。
完成效果图:
这里写图片描述
服务器端和客户端程序都需安装上,否则客户端无法获取数据。
service端的实现
这里写图片描述
其中*.aidl为AIDL的文件,是android系统提供的一种本地语言编写方式。
我们来看看这文件中都是什么:
Person.adil

package com.example.aidl;
parcelable Person;

看看这么写的原因:自定义的类必须实现 Parcelable 接口。Parcelable是android提供的一个比serializable效率更高的序列号接口(自行查看帮助文档,内有示例代码,注意读出顺序要和writeToParcel的写入顺序相同),还需要创建一个Person.aidl文件来声明你的parcelable 类。

UserInfo.aidl

package com.example.aidl;
import com.example.aidl.Person;
interface UserInfo{
    List<Person> getPersonList();
}

有没发现很简单,而且和java的风格很像,没错只要将写好的*.java给出后缀名为aidl即可。
Person类的实现
注意其中Parcelable的实现

public class Person implements Parcelable {
    public static final Creator<Person> CREATOR = new Parcelable.Creator<Person>() {

        @Override
        public Person createFromParcel(Parcel source) {
            // TODO Auto-generated method stub
            return new Person(source);
        }

        @Override
        public Person[] newArray(int size) {
            // TODO Auto-generated method stub
            return new Person[size];
        }
    };

    private Person(Parcel in) {
        name = in.readString();
        age = in.readInt();
        sex = in.readString();
    }

    private String name;
    private int age;
    private String sex;

    public Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    @Override
    public int describeContents() {

        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
        dest.writeString(sex);
    }

    public String toString() {
        return "姓名:" + name + " 年龄:" + age + "      性别:" + sex;
    }
}

service的简单实现

public class MyService extends Service {
    private List<Person> plist = new ArrayList<Person>();

    public MyService() {
        plist.add(new Person("张三", 4, "男"));
        plist.add(new Person("李四", 5, "女"));
    }

    private Binder mBinder = new UserInfo.Stub() {
        @Override
        public List<Person> getPersonList() throws RemoteException {
            // TODO Auto-generated method stub
            return plist;
        }

    };

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return mBinder;
    }
}

这里简单起见,之间存入两个person实例。
最后别忘了在AndroidManifest.xml中声明你的服务:

<service android:name=".MyService" >
            <intent-filter>
                <action android:name="com.example.AIDLCommunicationService.MyService" />
            </intent-filter>
        </service>

好了service端的基本实现了。有些不懂的地方可以再网上搜搜。
接下来是客户端的实现
client:
这里写图片描述
可以看到com.example.aidl中的东西和service中的一模一样,所有可以直接冲service中复制过来,因此我们要记住在是些类似的远程通讯的时候,关于aidl的部分最好反正一个包中,方便使用。
剩下的就是主函数从服务端中获取数据了。
看看代码

public class MainActivity extends Activity {
    private TextView tv_show;
    private Button bn_getData, bn_conn;
    private UserInfo userInfo;
    private Intent intent;
    private boolean haveConnection = false;
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            userInfo = UserInfo.Stub.asInterface(service);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent("com.example.AIDLCommunicationService.MyService");
        intent.setPackage("com.example.AIDLCommunicationService");
        init();
    }

    private void init() {
        tv_show = (TextView) findViewById(R.id.tv_content);
        bn_getData = (Button) findViewById(R.id.bn_getData);
        bn_conn = (Button) findViewById(R.id.bn_connetion);
    }

    public void connection(View v) {
        if (!haveConnection) {
            try {
                bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
                haveConnection = true;
                bn_getData.setClickable(true);
                tv_show.setText("已连接");
                bn_conn.setText("断开");
            } catch (Exception e) {
                bn_getData.setClickable(false);
                e.printStackTrace();
            }
        } else {
            unbindService(mConnection);
            haveConnection = false;
            bn_conn.setText("连接");
            bn_getData.setClickable(false);
        }
    }

    public void getData(View v) {
        try {
            List<Person> plist = userInfo.getPersonList();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < plist.size(); i++) {
                sb.append(plist.get(i).toString() + "\n");
            }
            tv_show.setText(sb.toString());
        } catch (RemoteException e) {
            tv_show.setText("获取失败,可能服务器,没开。");
            e.printStackTrace();
        }
    }
}

布局文件代码就不贴出了。可以下载工程自己看:
工程下载地址:点击下载
好了,搞定。一定要试着敲敲,这样印象更深刻。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值