android中的常用方法,Android中常见IPC方法总结

IPC (Interprocess communication)跨进程通信,是指在两个进程之间交换数据的过程。多进程通信一般分为两种情况。第一种,一个应用因为自身的需要采用多进程实现,比如某些模块由于特殊原因需要运行在单独的进程中。第二种情况,当前应用需要获得其它应用的数据,由于是两个应用,所以必须采用跨进程的方式。下面就对常用的IPC方法做一个总结。

使用Bundle

Activity,Service,Receiver都是支持在Intent中传递Bundle的,由于Bundle实现了Parcelable接口,所以他可以在不同进程间传输。我们可以在Bundle中附加数据,并通过Intent传送出去。当然,传送的数据必须是能够被序列化的。关于Android中序列化的知识可以参考http://blog.csdn.net/l664675249/article/details/49403333

使用文件共享

A进程把数据写入文件,B进程通过读取这个文件来获得数据。但这这种方法有一个问题就是并发读/写问题。有一个特例,SharedPreferences是Android中提供的轻量级存储方案,底层采用XML实现。但是对于他的读写有一定的缓存策略,因此不建议在进程间通信中使用他。

举例

在MainActivity的onResume中序列化一个对象到sd卡,然后再SecondActivity的onResume中反序列化。关键代码如下

//MainActivity

private void persistToFile() {

new Thread(new Runnable() {

@Override

public void run() {

User user = new User(1, "hello world", false);

File dir = new File(MyConstants.CHAPTER_2_PATH);

if (!dir.exists()) {

dir.mkdirs();

}

File cachedFile = new File(MyConstants.CACHE_FILE_PATH);

ObjectOutputStream objectOutputStream = null;

try {

objectOutputStream = new ObjectOutputStream(

new FileOutputStream(cachedFile));

objectOutputStream.writeObject(user);

Log.d(TAG, "persist user:" + user);

} catch (IOException e) {

e.printStackTrace();

} finally {

MyUtils.close(objectOutputStream);

}

}

}).start();

}

//SecondActivity

private void recoverFromFile() {

new Thread(new Runnable() {

@Override

public void run() {

User user = null;

File cachedFile = new File(MyConstants.CACHE_FILE_PATH);

if (cachedFile.exists()) {

ObjectInputStream objectInputStream = null;

try {

objectInputStream = new ObjectInputStream(

new FileInputStream(cachedFile));

user = (User) objectInputStream.readObject();

Log.d(TAG, "recover user:" + user);

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} finally {

MyUtils.close(objectInputStream);

}

}

}

}).start();

}

使用Messenger

Messenger是一种轻量级的IPC方案,他的底层实现时AIDL。他是以串行的方式处理客户端发来的消息的,一次处理一个请求,因此我们不考虑线程同步问题。

下面是一个例子,客户端向服务端发送一个请求,服务的接到请求后向客户端返回一个消息,Service是注册在另外一个进程中的。

MessengerService

public class MessengerService extends Service {

private static final String TAG = "MessengerService";

private static class MessengerHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MyConstants.MSG_FROM_CLIENT:

Log.i(TAG, "receive msg from Client:" + msg.getData().getString("msg"));

Messenger client = msg.replyTo;

Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE);

Bundle bundle = new Bundle();

bundle.putString("reply", "嗯,你的消息我已经收到,稍后会回复你。");

relpyMessage.setData(bundle);

try {

client.send(relpyMessage);

} catch (RemoteException e) {

e.printStackTrace();

}

break;

default:

super.handleMessage(msg);

}

}

}

private final Messenger mMessenger = new Messenger(new MessengerHandler());

@Override

public IBinder onBind(Intent intent) {

return mMessenger.getBinder();

}

@Override

public void onCreate() {

super.onCreate();

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

return super.onStartCommand(intent, flags, startId);

}

}

MessengerActivity

public class MessengerActivity extends Activity {

private static final String TAG = "MessengerActivity";

private Messenger mService;

private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());

private static class MessengerHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MyConstants.MSG_FROM_SERVICE:

Log.i(TAG, "receive msg from Service:" + msg.getData().getString("reply"));

break;

default:

super.handleMessage(msg);

}

}

}

private ServiceConnection mConnection = new ServiceConnection() {

public void onServiceConnected(ComponentName className, IBinder service) {

mService = new Messenger(service);

Log.d(TAG, "bind service");

Message msg = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);

Bundle data = new Bundle();

data.putString("msg", "hello, this is client.");

msg.setData(data);

msg.replyTo = mGetReplyMessenger;

try {

mService.send(msg);

} catch (RemoteException e) {

e.printStackTrace();

}

}

public void onServiceDisconnected(ComponentName className) {

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_messenger);

Intent intent = new Intent("com.ryg.MessengerService.launch");

bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

}

@Override

protected void onDestroy() {

unbindService(mConnection);

super.onDestroy();

}

}

注:

Service

Service中有一个Handler,用来处理Client发来的消息,并在Handler中新建一个Messenger client = msg.replyTo来向客户端返回消息。

在onBind中返回他里面的Binder对象

Client

为了接收服务端的消息,客户端也需要准备一个接收消息的Messenger和Handler。

msg.replyTo = mGetReplyMessenger,当客户端发送消息的时候,需要把接收服务端回复的Messenger通过Message的replyTo参数传给服务端。

AIDL

Messenger以串行的方式处理客户端发来的消息的,一次处理一个请求,如果有大量的并发请求,那么用Messenger就不合适了,需要用AIDL。关于AIDL的讲解请参考http://blog.csdn.net/l664675249/article/details/50649676

ContentProvider

ContentProvider是Android中专门用于应用间进行数据共享的方式。详细示例请阅读书本P93.

Socket

实现思路,首先在远程Service建立一个TCP服务,然后在主界面中链接TCP服务,连接上后就可以给服务端发消息,服务端随机会随机回应一句话。关于Socket的讲解已经很多了,这里就不在赘述。

总结

IPC方式的优缺点和适用场景

8a6b13d64b54c71e3162e866d704cd16.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值