思路:
1、创建两个工程:MemoryFileService和MemoryFileClient,其中sevice端创建两个aidl文件:IMemoryService.aidl 和IMemoryServiceCallback.aidl。
2、service端负责跟新memoryfile的内容,client读取memoryfile的内容,service通过回调通知client端内容已经准备好,client通过service的接口告诉service端读取操作已经完成,简单的实现读写同步的问题。
- IMemoryService.aidl:
package com.example.memoryfileservice.aidl;
import android.os.IInterface;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import com.example.memoryfileservice.aidl.IMemoryServiceCallback;
interface IMemoryService {
void addCallback(IMemoryServiceCallback cb);
void removeCallback(IMemoryServiceCallback cb);
int readBytes(out byte[] buffer, int srcOffset, int destOffset, int count);
void writeBytes(in byte[] buffer, int srcOffset, int destOffset, int count);
int length();
void notifyFinish();
}
addCallback/removeCallback: client端注册/注销回调
readBytes/writeBytes: client端读写service端的memoryfile
length:返回memoryfile的长度
notifyFinish:通知service,读操作完成
- IMemoryServiceCallback.aidl
package com.example.memoryfileservice.aidl;
import android.os.IInterface;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
oneway interface IMemoryServiceCallback {
void onFrameAvaiable(int format, int size);
}
onFrameAvaible通知client端数据已经准备好!
- service端MemoryService:
package com.example.memoryfileservice;
import java.io.IOException;
import com.example.memoryfileservice.aidl.IMemoryService;
import com.example.memoryfileservice.aidl.IMemoryServiceCallback;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.MemoryFile;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
public class MemoryService extends Service {
private final static String TAG = "server";
private final static String MEMOERY_FILE_NAME = "cyq_mem";
private static final int SIZE_1M = 1024 * 1024;
private MemoryFile mMemoryFile = null;
private static final int REPORT_MSG = 1;
final RemoteCallbackList mCallbacks = new RemoteCallbackList(){
@Override
public void onCallbackDied(IMemoryServiceCallback callback, Object cookie) {
int N = mCallbacks.beginBroadcast();
log(N);
mCallbacks.finishBroadcast();
log("died = " + mCallbacks.unregister(callback));
}
};
@Override
public IBinder onBind(Intent intent) {
log(" onBind");
return mStub;
}
@Override
public boolean onUnbind(Intent intent) {
log(" onUnbind");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
log("onCreate");
super.onCreate();
try{
mMemoryFile = new MemoryFile(MEMOERY_FILE_NAME, SIZE_1M);
}
catch(IOException e){
log(e);
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
log("Received start id " + startId + ": " + intent);
return START_NOT_STICKY;
}
@Override
public void onStart(Intent intent, int startId) {
log("onStart");
}
@Override
public void onDestroy() {
log("onDestroy");
mCallbacks.kill();
mMemoryFile.close();
}
private final IMemoryService.Stub mStub = new IMemoryService.Stub() {
/*@Override
public ParcelFileDescriptor getFileDescriptor() throws RemoteException {
ParcelFileDescriptor pfd = null;
try {
//pfd = mMf.getParcelFileDescriptor();
//reflect method
Method method = MemoryFile.class.getDeclaredMethod("getFileDescriptor");
FileDescriptor fd = (FileDescriptor) method.invoke(mMemoryFile);
pfd = ParcelFileDescriptor.dup(fd);
} catch(Exception ex) {
log("Failed to get file descriptor.");
ex.printStackTrace();
}
return pfd;
}*/
@Override
public int readBytes(byte[] buffer, int srcOffset, int destOffset,
int count) throws RemoteException {
int ret = -1;
if(mMemoryFile != null){
try {
ret = mMemoryFile.readBytes(buffer, srcOffset, destOffset, count);
} catch (IOException e) {
log(e);
e.printStackTrace();
}
}
return ret;
}
@Override
public void writeBytes(byte[] buffer, int srcOffset, int destOffset,
int count) throws RemoteException {
if(mMemoryFile != null){
try {
printByte(buffer, count);
mMemoryFile.writeBytes(buffer, srcOffset, destOffset, count);
} catch (IOException e) {
log(e);
e.printStackTrace();
}
}
}
@Override
public int length() throws RemoteException {
int len = 0;
if(mMemoryFile != null){
len = mMemoryFile.length();
}
return len;
}
@Override
public void addCallback(IMemoryServiceCallback cb) throws RemoteException {
if (cb != null) {
mCallbacks.register(cb);
mHandler.sendEmptyMessage(REPORT_MSG);
}
}
@Override
public void removeCallback(IMemoryServiceCallback cb) throws RemoteException {
if (cb != null) mCallbacks.unregister(cb);
}
@Override
public void notifyFinish() throws RemoteException {
mHandler.sendEmptyMessageDelayed(REPORT_MSG, 2*1000);
}
};
private final Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
// It is time to bump the value!
case REPORT_MSG: {
// Broadcast to all clients the new value.
final int N = mCallbacks.beginBroadcast();
for (int i=0; i
- Client端MainActivity的代码:
package com.example.memoryfileclient;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import com.example.memoryfileservice.aidl.IMemoryService;
import com.example.memoryfileservice.aidl.IMemoryServiceCallback;
public class MainActivity extends Activity {
private static final String TAG = "client";
private IMemoryService mProxy;
boolean mIsBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
log("service disconnected");
mIsBound = false;
try {
mProxy.removeCallback(mCallback);
mProxy = null;
} catch (RemoteException e) {
log(e);
e.printStackTrace();
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
log("service connected ");
mProxy = IMemoryService.Stub.asInterface(service);
try {
log("addCallback");
mProxy.addCallback(mCallback);
log("length = " + mProxy.length());
} catch (RemoteException e) {
log(e);
e.printStackTrace();
}
mIsBound = true;
readWriteTest();
}
};
private void readWriteTest()
{
if(!mIsBound){
return;
}
byte[] w_buf = new byte[16];
byte[] r_buf = new byte[16];
for(int i = 0; i < w_buf.length; i++){
w_buf[i] = (byte) i;
}
try {
mProxy.writeBytes(w_buf, 0, 0, 16);
mProxy.readBytes(r_buf, 0, 0, 16);
printByte(r_buf, 16);
} catch (RemoteException e) {
log(e);
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
log("Activity onCreate ");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindRemoteServcie();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mConnection != null)
unbindService(mConnection);
}
public void onNotifyClick(View v) throws RemoteException{
if(mProxy != null){
//log( "t1 = " + System.currentTimeMillis());
mProxy.notifyFinish();
}
}
public void onRemoveClick(View v) throws RemoteException{
if(mProxy != null){
mProxy.removeCallback(mCallback);
}
}
private IMemoryServiceCallback mCallback = new IMemoryServiceCallback.Stub() {
@Override
public void onFrameAvaiable(int format, int size) throws RemoteException {
log("onFrameAvaiable: format = " + format + ", size = " + size);
mProxy.notifyFinish();
}
};
private void bindRemoteServcie() {
Intent i = new Intent();
i.setAction("com.myaction.MemoryService");
i.setPackage("com.example.memoryfileservice");
log("bindService begin");
try{
boolean result = bindService(i, mConnection, Context.BIND_AUTO_CREATE);
log("bind result = " + result);
}catch(Exception e){
log(e);
}
}
private void printByte(byte[] r_buf, int len) {
String s = new String();
for(int i = 0; i < len; i++){
s += r_buf[i] + ",";
}
log(s);
}
private void log(Object o) {
Log.d(TAG, "" + o);
}
}
完整源码下载,挣点分数,哈哈