所谓跨进程调用,在 Android 应用开发中,就是不同了两个应用程序进程之间的通信实现。
我们姑且将这个两个通信的应用程序进程区分为客户端和服务端。
下面就以两个简单的应用程序来了解如何实现 Android 应用开发的跨进程通信。
这两个应用的实现很简单,就是实现在客户端点击 "设置用户名" 按钮往服务端输入用户名,然后又在客户端点击 "获取用户名" 按钮,获取服务端保存的用户名。
服务端:一个继承 Service 的类,以及一个 aidl 文件。(关于 aidl 文件还是用上一篇文章的 IMyService.aidl)
IMyService.aidl 的定义如下:
- interface IMyService {
- String getName();
- void setName(String name);
- }
针对创建的 IMyService.aidl,eclipse 会自动在工程的 gen 目录中生成 IMyService.java 文件,这时候可以将这个 java 文件移到工程的 src 目录。然后删掉之前在 src 目录创建的 IMyService.aidl 就可以了。(注意,别忘了在 IMyService.java 文件代码中添加你自己创建的工程包名)
继承 Service 类的远程服务类代码 package com.feixun.hu.ipc.service;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteException;
- public class IpcService extends Service { //用于保存客户端输入的用户名private String userName;private ServiceBinder mServiceBinder;@Overridepublic void onCreate(){// TODO Auto-generated method stubsuper.onCreate();//创建ServiceBinder对象(Binder类型对象)mServiceBinder = new ServiceBinder();}/*定义一个继承IMyService接口内部类Stub的实现与客户端通信的Binder类型的类,* IMyService.Stub是Binder类型*/public class ServiceBinder extends IMyService.Stub{@Overridepublic String getName() throws RemoteException{// TODO Auto-generated method stubreturn userName;}@Overridepublic void setName(String name) throws RemoteException{// TODO Auto-generated method stubuserName = name;}}@Overridepublic IBinder onBind(Intent arg0){// TODO Auto-generated method stub/*与客户端连接时,返回该Binder对象.* 1.如果连接的客户端和该服务端属于同一个进程,则此处直接返回mServiceBinder本身* 2.如果连接的客户端和该服务不属于同一个进程,则返回的是mServiceBinder对象的代理*/return mServiceBinder;}}
AndroidManifest.xml 文件代码如下: (注:文件中添加的 action>"com.feixun.hu.action.IPC_SERVICE"对应的是在客户端中绑定该服务设置添加的 action)
本文所谓的服务端,也就是创建一个应用程序工程,该应用程序包含一个 Service。所以,该服务端应用程序运行时是不可见的。
客户端:一个继承 Activity 的类,和服务端一摸一样的 IMyService.aidl 文件 (这个文件是实现两者之间进行通信必不可少的。可以直接把服务端自动生成的 IMyService.java 复制过去客服端)。
继承 Activity 的可视化类的代码如下:
- package com.feixun.hu.ipc.client;
- import android.app.Activity;
- import android.app.Service;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- public class IpcClient extends Activity {
- private IMyService mIMyService;
- private Button setName,
- getName;
- private TextView show;
- private EditText input;
- /** Called when the activity is first created. */
- @Overridepublic void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main); //获取各组件setName = (Button)findViewById(R.id.set);getName = (Button)findViewById(R.id.get);show = (TextView)findViewById(R.id.show);input = (EditText)findViewById(R.id.input);//创建Intent,对应服务端注册的IntentIntent intent = new Intent();intent.setAction("com.feixun.hu.action.IPC_SERVICE");//绑定连接远程服务bindService(intent, conn, Service.BIND_AUTO_CREATE);//为设置按钮绑定监听setName.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){// TODO Auto-generated method stubif(input.getText() != null){try{//将输入的信息保存到远程服务端mIMyService.setName(input.getText().toString());}catch (RemoteException e){// TODO Auto-generated catch blocke.printStackTrace();}}}});//获取按钮绑定监听getName.setOnClickListener(new OnClickListener(){//String name = mIMyService.getName();@Overridepublic void onClick(View v){// TODO Auto-generated method stubtry {if(mIMyService.getName() != null){show.setText(mIMyService.getName().toString());}} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}//实现客户端与服务端绑定的关键部分private ServiceConnection conn = new ServiceConnection(){//解除连接服务端@Overridepublic void onServiceDisconnected(ComponentName name){// TODO Auto-generated method stubmIMyService = null;}//连接服务端@Overridepublic void onServiceConnected(ComponentName name, IBinder service){// TODO Auto-generated method stub/*此处实现获取通过IpcService的onBind方法返回的mServiceBinder对象的代理。* 参数service为绑定获得的远程服务IpcService的mServiceBinder对象,* 而调用IMyService.Stub的函数asInterface获取的是mServiceBinder对象的代理。*/mIMyService = IMyService.Stub.asInterface(service);}};@Overrideprotected void onDestroy(){// TODO Auto-generated method stubsuper.onDestroy();//解除绑定unbindService(conn);}}
本文所谓的客户端,也是创建一个应用程序工程,该工程包含一个 Activity,用户通过操作该 Activity 所提供的可视化组件界面,向远处服务端 (也就是在另一个应用程序进程中运行的 Service 服务) 保存数据、获取数据。
以上两个简单的应用程序例子,可以实现两个应用程序之间的最基本的跨进程通信了。当然,有需要时,我们还可以创建传输和处理更复杂的数据远程服务,而不单单是本文所创建的例子那么简单。比如,以一个类的形式 (类似 JavaBean) 为数据,而此时,这个数据类是要求要实现 Parcelable 接口的。(根据 AIDL 文件定义的接口限定的数据类型要求的)
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/03-08/18349590.html