二、IPC机制续(IPC方式)
来源:互联网 发布:sql 存储过程举例 编辑:程序博客网 时间:2024/05/02 01:56
IPC机制
具体方式有很多,比如可以在Intent中附加Extra来传递信息,或者通过共享文件的方式来共享数据,还可以采用Binder方式来跨进程通信,另外,Content Provider天生就是支持跨进程访问的,因此,我们也可以使用它来进行IPC,另外通过网络通信也是可以实现数据传递的,所以Socket也可以实现IPC。
1.使用Bundle
由于Bundle实现了Parcelable接口,所以它可以方便地在不同进程间传输。
除了直接传递数据这种典型的使用场景,他还有一种特殊的使用场景,如A进程正在进行计算,计算完成之后需要把结果传递给B进程,但是这个结果不支持放入Bundle中,那么可以这样考虑,A中,通过Intent启动B进程的一个Service组件(如IntentService),让Service进行后台计算,计算完毕之后,再启动B进程中真正想要启动的组件由于Service也在B进程中,所以目标组件就可以直接获取结果。
findViewById(R.id. button).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(MainActivity. this, SecondActivity.class); User user = new User(0, "jake", true); user. book = new Book(); intent.putExtra( "extra_user", (Serializable) user); startActivity( intent); } });
2.使用文件共享
两个进程通过读写同一个文化夹来交换数据,比如A进程把数据写进文件,B进程通过读取这个文件来获取数据。Linux使得并发读写文件可以没有限制,甚至两个线程同时对一个文件进行读写都是运行的。
希望在ManActivity中的onResume中序列化一个User对象到SDk卡上面的一个文件里面,在SecondActivity的onResume中去反序列化。
MainActivity:onResume执行下面的方法
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();}
当然这种不支持并发,如果想要并发,需要使用线程同步机制来解决。SharePreferences是个特例,通过键值对来存储数据,底层采用xml来存储键值对,位置在/data/data/packagename/shared_prefs目录下面,从本质来说SharePreferences也属于文件的一种,但是由于系统对它的读写有一定的缓存策略,即在内存里面有一份SharePreferences文件的缓存,因此在多进程模式下,系统对他的读写变得不可靠,当面对高并发的读写访问就有很大几率丢失数据,因此不建议进程间通信使用SP。
3.使用Messenger
Messenger是一种轻量级的IPC方案,它的底层实现是AIDL。从构造方法可以很明显的看出AIDL的痕迹。
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
Messenger的使用方法很简单,它对AIDL做了封装,使得我们可以更简单地进行线程间通信,同时由于它一次处理一个请求,因此在服务端我们不用考虑线程同步的问题,这个是因为服务端不存在并发执行的情况。
步骤:
1.服务端进程,首先我们要创建一个Service来处理客户端的请求,同时创建一个Handler并通过它来创建一个Messenger对象,在Service的onBind里面返回这个Messenger对象底层的Binder即可。
2.客户端进程,首先要绑定服务端的Service,绑定成功之后用服务端返回的IBinder对象创建一个Messenger,通过这个Messenger就可以向服务端发送消息了发送消息类型为Message对象。
如果要服务端能够回应客户端,就和服务端一样,需要创建一个Handler并创建一个新的Messenger,并把这个Messenger对象通过Message的replyTo参数传递给服务端,服务端通过这个replyTo参数就可以回应客户端。
服务端:
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);
}
}
客户端:
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();
}
}
Mainfest里面:
- 二、IPC机制续(IPC方式)
- 二、IPC机制续(IPC方式)
- IPC 机制(二)
- IPC机制(二)
- IPC机制(二)
- 二、IPC机制(IPC介绍)
- 【Android】IPC机制(二)
- android IPC机制(二)
- Android IPC机制(二)
- IPC机制之四:IPC方式(AIDL)
- IPC机制---04 Android中的IPC通讯方式(A)
- IPC机制---04 Android中的IPC通讯方式(B)
- IPC机制---04 Android中的IPC通讯方式(C)
- IPC机制---04 Android中的IPC通讯方式(D)
- IPC机制---04 Android中的IPC通讯方式(E)
- 4.IPC 机制(二) IPC基础概念介绍
- 读书笔记--IPC机制(二)
- IPC机制<二>AIDL
- ES6语法篇(其一)
- maven 工程启动找不到 Spring ContextLoaderListener 的解决办法
- 如何让你的App更流畅
- Android listview设置多个不同的item样式
- ThreadLocal的使用
- 二、IPC机制续(IPC方式)
- oracle之merge的深入介绍
- 库出错啦
- 抽奖的概率算法。
- 适配 Android N 需要注意什么
- Spring MVC 同一个方法同时返回view或json
- SQL Server Version
- ExtJS4中GridPanel组件简单例子
- RxJava