序列化接口Parcelable
为什么会有序列化这么个东西?
简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来。
虽然你可以用你自己的各种各样的方法来保存,但是Java已经提供一个完善的接口来进行序列化的工作,那就是Serializable。
序列化的使用场景
- 永久性保存对象,保存对象的字节序列到本地文件中;
- 通过序列化对象在网络中传递对象;
- 通过序列化在进程间传递对象。
Parcelable又是什么?
Parcelable是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC)
Parcelable和Serializable如何选择?
- 在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
- Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
- Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
注意:writeToParcel和参数为Parcel的构造方法,里面的读写顺序一定要一致
Android 进程间通信(IPC)
假设要做一个音乐播放的App,除去前台UI展示,还要能够后台播放,实现方案分析可以查看这篇博文,讲的很深入了。
我们就采用多进程的方式来实现这个需求吧。
项目结构
Project视图下可能看的更清楚,在AS中new直接选择AIDL-AIDL File即可自动生成。
- MediaService就是跑在另一个进程中的后台服务,负责播放音乐文件。
- MusicTrack是bean类。
- 要想在AIDL使用到bean类,需要生命与java文件对应的同名aidl文件,即 MusicTrack.aidl
- MusicAIDLService.aidl 就是远程服务接口声明。
注意同名的java文件和aild文件的包名需要一样。
代码
在写完AIDL和bean类之后,编译一下工程,AS会自动生成后续我们需要使用的代理类 MusicAIDLService.Stub,这个类是AS根据AIDL文件,自动创建的,在app/build/generated/source/aidl/debug/
目录下, MusicAIDLService.Stub就是一个Binder的子类,后续就跟普通的Service的使用没有区别了。1
2
3
4
5
6
7
8
9
10
11
12//MusicAIDLService.aidl 声明远程进程方法 在Service重载
package com.dongua.ipc.service;
import com.dongua.ipc.service.MusicTrack;
interface MusicAIDLService{
void play();
void pause();
void stop();
void prev();
void next();
MusicTrack getCurrentTrack();
}
1 | //MusicTrack.aidl |
1 | //MusicTrack.java 用来多进程之间传输的数据需要实现Parcelable接口 |
1 | public class MediaService extends Service { |
1 | //MainActivity.java |
输出
1 | 10-16 20:58:48.257 22211-22211/com.dongua.ipc:music I/MediaService: onCreate: |
如果你只是想要了解如何使用AIDL来完成进程间的通信,实现功能即可,对底层的细节不感兴趣,那么后续的直接套上面的模板来,或者使用基于AIDL封装的更加完善的Messenger(注意与Message区别)来完成相应的需求即可。