android IPC_service
来源:互联网 发布:cf卡数据恢复软件 mac 编辑:程序博客网 时间:2024/06/01 15:05
android IPC_service
Android中进程间的通信提供了四种方式,分别是四大组件,其中Activity可以通过Intent跨进程调用其他应用程序的Activity;ContentProvider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操作;Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播;Service和ContentProvider类似,也可以访问其他应用程序中的数据,但不同的是,Content Provider返回的是Cursor对象,而Service返回的是IBinder对象,这种可以跨进程通讯的服务叫AIDL服务。
Android Service分为两种:
本地服务(Local Service): 同一个apk内被调用
远程服务(Remote Service):被另一个apk调用
远程服务需要借助AIDL(Android InterfaceDefinition Language)或者Messenger来完成,其实Messenger也是用AIDL实现的,只不过是google对其进行了封装,使用比AIDL相对简单一些。
实现一下AIDL使其在两个应用程序(两个进程)中进行进程间通信(interprocess communication,IPC),新建两个android应用程序,我们在src目录下新建一个com.aidls包,com.aidl包下新建一个后缀为.aidl的文件,文件中添加一段代码:
package com.aidls;
interface holdService {
void play();
void stop();
}
这个感觉和接口interface的使用差不多,只不过interface定义在.java文件中,但是aidl中不能加public等修饰符,保存后编译器会在gen目录下生成一个holdService.java文件,这时候这个aidl文件就建成功了
然后我们在com.services中建一个后台播放音乐的service:
publicclass PlayerServiceextends Service {
publicstaticfinal StringTAG ="PlayerService";
privateMediaPlayer mplayer;
@Override
publicIBinder onBind(Intent intent) {
Log.i(TAG,"serviceonbind");
if(mplayer==null){
mplayer =new MediaPlayer();
try {
FileDescriptor fd =getResources().openRawResourceFd(R.raw.lost).getFileDescriptor(); //获取音乐数据源
mplayer.setDataSource(fd); //设置数据源
mplayer.setLooping(true); //设为循环播放
}catch (IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG,"playercreated");
}
returnmBinder;
}
//实现aidl文件中定义的接口
privateIBinder mBinder =newholdService.Stub() {
@Override
publicvoid stop()throwsRemoteException {
try {
if (mplayer.isPlaying()) {
mplayer.stop();
}
}catch (Exception e) {
//TODO: handle exception
e.printStackTrace();
}
}
@Override
publicvoid play()throwsRemoteException {
try {
if (mplayer.isPlaying()) {
return;
}
mplayer.prepare();
mplayer.start();
}catch (Exception e) {
//TODO: handle exception
e.printStackTrace();
}
}
};
@Override
publicboolean onUnbind(Intent intent){
if(mplayer !=null) {
mplayer.release();
}
Log.i(TAG,"serviceonUnbind");
returnsuper.onUnbind(intent);
}
}
这里的播放服务就不用多说,主要看service,继承service后必须要实现onBind()方法,这个方法返回的是一个IBinder,进程间的通信离不开Binder,所以这里我们new holdService.Stud(),他返回的刚好是一个IBinder对象,我们可以看一下holdService.Stud()方法的源码,他也是exendsandroid.os.Binder,实例化后会必须实现play()和stop()方法,我们发现两个方法刚好是上面在com.aidls->holdservice.aidl中定义的两个方法,我们分别在play(),和stop()中实现音乐的播放和停止,然后在清单文件中注册这个服务 ,必须在过滤intent中定义action
<serviceandroid:name=".PlayerService" android:process=":remote">
<intent-filter >
<action android:name="com.example.playerserver.PlayerService"/>
</intent-filter>
</service>
到此地一个应用程序就结束了
新建第二应用程序,这时候必须把com.aidls和下面的aidl原封不动的一起复制过来,当然,自己在敲一边aidl文件保存一下,也是一样的,然后在com.activity中做一个activity
publicclass sextends Activityimplements OnClickListener{
privateholdService holdservice=null;
privateButtonplay;
privateButtonstop;
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent service =new Intent("com.example.playerserver.PlayerService ");
bindService(service, mConnection,BIND_AUTO_CREATE);
play=findViewById(R.id.play);
stop=findViewById(R.id.stop);
}
privateServiceConnection mConnection =newServiceConnection(){
@Override
publicvoidonServiceConnected(ComponentName name, IBinder service) {
//TODO Auto-generated method stub
holdservice = holdService.Stub.asInterface(service);
}
@Override
publicvoidonServiceDisconnected(ComponentName name) {
//TODO Auto-generated method stub
holdservice =null;
}
};
@Override
publicvoid onClick(View v) {
//TODO Auto-generated method stub
switch (v.getId()) {
caseR.id.play:
holdservice.play();
break;
caseR.id.stop:
holdservice.stop();
break;
default:
break;
}
}
@Override
protectedvoid onDestroy() {
//TODO Auto-generated method stub
super.onDestroy();
unbindService(mConnection);
}
}
先绑定服务,这里绑定的时候要实现ServiceConnection,ServiceConnection下要实现两个方法,在onServiceConnected绑定服务,他有两个参数,其中service就是上一个应用程序的service中onBind返回的IBinder,这里通过holdService.Stub
.asInterface方法获取Service建立本地代理,这时候我们在第二个应用程序中就可以控制第一个应用程序应用的播放和停止
这里我们可以看出在第二个应用程序可以调用地一个应用程序service中的play(),stop(),这两个函数是void类型,那么我们也可以是int,char的类型来传递数据了,但是我们需要注意的是:
AIDL服务只支持有限的数据类型,如果用AIDL服务传递一些复杂的数据就需要做更一步处理, AIDL 服务支持的数据类型如下:
1. Java 的原生类型
2. String 和CharSequence
3. List 和 Map ,List和Map对象的元素必须是AIDL支持的数据类型; 以上三种类型都不需要导入(import)
4. AIDL 自动生成的接口 需要导入(import)
5. 实现android.os.Parcelable接口的类. 需要导入(import)。
那么我们要自定义Bean——Person类传递过去,Person是一个序列化的类,这里使用Parcelable接口来序列化,Parcelable是Android提供的一个比Serializable效率更高的序列化类。
我们在地一个应用程序的aidl文件中添加
package com.aidls;
import com.entity.Book;
interface holdService {
void play();
void stop();
Book getBook();
}
注意这里要导入Book
我们去生成一个Book实现Parcelable接口
publicclass Bookimplements Parcelable{
privateString bookName;
privateint bookPrice;
publicBook(){
}
publicBook(Parcel parcel){
bookName = parcel.readString();
bookPrice = parcel.readInt();
}
publicString getBookName() {
returnbookName;
}
publicvoid setBookName(StringbookName) {
this.bookName= bookName;
}
publicint getBookPrice() {
returnbookPrice;
}
publicvoid setBookPrice(int bookPrice) {
this.bookPrice= bookPrice;
}
@Override
publicint describeContents() {
//TODO Auto-generated method stub
return0;
}
@Override
publicvoid writeToParcel(Parcel dest,int flags) {
//TODO Auto-generated method stub
dest.writeString(bookName);
dest.writeInt(bookPrice);
}
publicstaticfinal Parcelable.Creator<Book>CREATOR =newCreator<Book>(){
@Override
publicBook createFromParcel(Parcel source) {
//TODO Auto-generated method stub
returnnewBook(source);
}
@Override
publicBook[] newArray(int size) {
//TODO Auto-generated method stub
returnnewBook[size];
}
};
}
因为我们在aidl文件中加了getBook()方法,这时候在service的 private IBinder mBinder =new holdService.Stub() {}
中我们就必须实现getBook方法,这里我们直接赋值
//实现aidl文件中定义的接口
privateIBinder mBinder =newholdService.Stub() {
@Override
publicvoid stop()throws RemoteException {
try {
if (mplayer.isPlaying()) {
mplayer.stop();
}
}catch (Exception e) {
//TODO: handle exception
e.printStackTrace();
}
}
@Override
publicBook getBook()throws RemoteException{
Book mBook =new Book();
mBook.setBookName("Android应用开发");
mBook.setBookPrice(50);
return mBook;
}
@Override
publicvoid play()throws RemoteException {
try {
if (mplayer.isPlaying()) {
return;
}
mplayer.prepare();
mplayer.start();
}catch (Exception e) {
//TODO: handle exception
e.printStackTrace();
}
}
};
在第二个程序用(当然Book和aidl同样要复制到第二个应用程序中)
@Override
publicvoidonServiceConnected(ComponentName name, IBinder service) {
//TODO Auto-generated method stub
holdservice = holdService.Stub.asInterface(service);
Stringbookname=holdservice.getBook().getBookName();
}
以此就可以得到book对象
- android IPC_service
- ipc_service 类:阻塞与非阻塞混合编程
- Android
- android
- Android
- android
- android
- Android
- Android
- android
- android
- android
- Android
- Android
- android!!!
- android
- android
- android
- 提高HTML5 canvas性能的几种方法!
- HDU 1042 N!
- 第十三周项目5——将两个字符串连接并保存到第三个字符串中
- PorterDuff.Mode
- matlab图像配准2
- android IPC_service
- Android 开发之旅:view的几种布局方式及实践
- 第12周项目 3.1 递归 阶乘
- 第十四周 项目3.1 多科成绩处理
- 人品计算器
- 函数版星号图
- PHP 上传文件大小限制
- 第14周 项目2-带姓名的名单(2)
- 选择屏幕按钮