先做服务器端:
服务端继承Service,里面带了一个 mBinder,
mBinder其实就是客户端在 服务端的 映射接口,
在客户端 通过 transact 发送数据
mIBinder.transact(1, data, reply, 0);
服务端的 mBinder 就能接受数据 触发 onTransact 事件
public class H264Service extends Service {
private H264Binder mBinder = new H264Binder();
public H264Service() {
}
static {
System.loadLibrary("native-lib");
}
public static final String TAG = "H264Svr";
private ParcelFileDescriptor pfd;
private class H264Binder extends Binder {
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
switch (code) {
case 0x001: {
Log.d(TAG, "onTransact() executed");
pfd=data.readFileDescriptor();
GetShareMem(pfd.getFileDescriptor());
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
}
@Override
public void onCreate() {
super.onCreate();
test=new byte[1024];
int i;
for(i=0;i<100;i++) test[i]=(byte)i;
Log.d(TAG, "onCreate() executed");
Log.d(TAG, "process id is ");
new Thread(new Runnable() {
@Override
public void run() {
// 开始执行后台任务
int nCnt=0;
while (true){
nCnt++;
Log.d("CNT","Hello:"+nCnt);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand() executed");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy() executed");
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
//throw new UnsupportedOperationException("Not yet implemented");
// return new H264Binder();
Log.d(TAG, "onBind() executed");
return mBinder;
}
}
服务端的 AndroidManifest.xml 在创建 H264Service 自动增加下面绿色部分,红色部分 是声明 server是在单独的进程里面,不和ui同一个进程,蓝色部分是为了显式调用 server 做的声明
<service android:name=".H264Service" android:enabled="true" android:exported="true" android:process=":remote"> <intent-filter> <action android:name="com.yiyo.h264svr.H264Service"/> </intent-filter> </service>
客户端的代码如下:
这里 通过按键 R.id.button_update 的点击 链接 server
链接的参数 和 <action android:name="com.yiyo.h264svr.H264Service"/> 相关
Intent service = new Intent("com.yiyo.h264svr.H264Service");
service.setPackage("com.yiyo.h264svr");
onServiceConnected 就是链接成功返回的事件
private IBinder mIBinder;
private ServiceConnection PersonConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mIBinder = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Parcel data, reply;
mIBinder = service;
try {
// 写一次 , 读取数据后 数据会被清空
// 持续写,不读,数据不会清空,注意数据覆盖(offset值)
Method getFileDescriptorMethod = m_fd.getClass().getDeclaredMethod("getFileDescriptor");
if(getFileDescriptorMethod != null){
FileDescriptor fileDescriptor = (FileDescriptor) getFileDescriptorMethod.invoke(m_fd);
// 不需要这句 也能正确传输
//ParcelFileDescriptor pfd =ParcelFileDescriptor.dup(fileDescriptor);
if(mIBinder!=null){
//data.writeParcelable(pfd, 0);
// 或者
data=Parcel.obtain();
reply=Parcel.obtain();
data.writeFileDescriptor(fileDescriptor);
mIBinder.transact(1, data, reply, 0);
data.recycle();
reply.recycle();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
class MyListener implements View.OnClickListener
{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_update:
Intent service = new Intent("com.yiyo.h264svr.H264Service");
service.setPackage("com.yiyo.h264svr");
bindService(service, PersonConnection, BIND_AUTO_CREATE);
break;