android 进程间通信(上)
1、Intent
2、Messenger
3、AIDL
使用Intent实现进程间通信
新建本地服务,远程服务。android中本地服务指的是当前app 、远程服务指的是目标app
两个app创建好就是app间跳转了。
从本地APP跳转到远程APP并传值
这里要注意的就是ComponentName 的参数 第一个参数远程app的包名,第二个参数是跳转到远程app的指定页面
本地app代码
public void goRemoteService(View view) {
Intent intent = new Intent();
ComponentName componentName=new ComponentName(
"com.finedo.remoteservice",
"com.finedo.remoteservice.RemoteActivity");
intent.setComponent(componentName);
intent.putExtra("userName","wy");
intent.putExtra("pwd","123456");
startActivity(intent);
}
远程app代码接收值
public class RemoteActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_remote);
Intent intent = getIntent();
if (intent != null) {
String userName = intent.getStringExtra("userName");
String pwd = intent.getStringExtra("pwd");
Log.e("wy", userName + pwd);
}
}
}
执行结果
使用Messenger实现进程间通信
同样需要新建本地服务,远程服务。
服务端部分
public class MessengerService extends Service {
private int SEND2CLIENT = 0x001;
private Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
Message message = Message.obtain(msg);
message.what = SEND2CLIENT;
Bundle data = msg.getData();//接收客户端发送过来的数据
String s = (String) data.get("client");
Log.e("wy", s);
Bundle bundle = new Bundle();
bundle.putString("service", "远程服务已完成身份证读取,现返回读取数据...");
message.setData(bundle);
try {
message.replyTo.send(message);//将Message 转换成Messenger发送消息给客户端
} catch (RemoteException e) {
e.printStackTrace();
}
super.handleMessage(msg);
}
});
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
别忘了在Manifest中注册Service(本Service 需要让客户端调用需要设置export=true)
<service
android:name=".MessengerService"
android:exported="true">
<intent-filter>
<action android:name="com.finedo.remoteservice.service" />
</intent-filter>
</service>
客户端部分
客户端分为连接远程服务端 发送数据 和接收服务端数据3个部分
连接服务端
/**
* 绑定服务
*/
private void bindService() {
Intent intent = new Intent();
intent.setAction("com.finedo.remoteservice.service");
//android 5.0以后需要指定服务端包名
intent.setPackage("com.finedo.remoteservice");
bindService(intent, mConn, BIND_AUTO_CREATE);
}
/**
* 连接服务
*/
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
Log.e("wy", "连接远程服务成功");
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
Log.e("wy", "连接远程服务失败");
}
};
向服务端发送数据
public void sendData(View view) {
if (mService != null) {
Message msg = Message.obtain();
msg.replyTo = messenger;
Bundle bundle=new Bundle();
bundle.putString("client","我是客户端的消息");
msg.setData(bundle);
try {
if (mService != null) {
mService.send(msg);
}
} catch (RemoteException e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, "连接远程服务失败", Toast.LENGTH_SHORT).show();
}
}
接收服务端的数据
private Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == SEND2SERVICE) {
Bundle data = msg.getData();
if (data != null) {
String m = (String) data.get("service");
Toast.makeText(MainActivity.this, m, Toast.LENGTH_SHORT).show();
Log.e("wy", m);
}
}
super.handleMessage(msg);
}
});
下面是执行后的结果
客户端部分
服务端部分
使用AIDL实现进程间通信
服务端
新建IService.aidl接口
interface IService {
String callMethodRemote();//调用远程服务中的方法
}
创建远程服务Service
public class RemoteService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
//远程服务中的方法
public String methodRemote() {
return "我是远程服务的方法";
}
private class MyBinder extends IService.Stub {
@Override
public String callMethodRemote() throws RemoteException {
return methodRemote();
}
}
}
AS中aidl 文件的目录结构
在Manifest中注册Service
<service
android:name=".RemoteService"
android:exported="true">
<intent-filter>
<action android:name="com.wy.service" />
</intent-filter>
</service>
到此服务端的代码就完成了
下面是创建客户端了
将远程服务中的IService 复制到客户端 注意包名与服务端保持一致
接着就是连接服务端
private void bindService() {
Intent intent = new Intent();
intent.setAction("com.wy.service");
intent.setPackage("com.wy.remoteservice");
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
}
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iService = IService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
调用服务端中的方法
String s = iService.callMethodRemote();
运行结果
到此为止android中的最常用的IPC就介绍完了,关于socket实现进程间通信会在下篇中更新,敬请期待~
最后附上下载地址
demo地址