MemoryFile实现进程间内存共享

思路:

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<IMemoryServiceCallback> mCallbacks = new RemoteCallbackList<IMemoryServiceCallback>(){
		@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<N; i++) {
                        try {
                            mCallbacks.getBroadcastItem(i).onFrameAvaiable(0, mMemoryFile.length());
                        } catch (RemoteException e) {
                            // The RemoteCallbackList will take care of removing the dead object for us.
                        	log(e);
                        }
                    }
                    mCallbacks.finishBroadcast();
                    // Repeat every 5 second.
                    //sendMessageDelayed(obtainMessage(REPORT_MSG), 5*1000);
                } break;
                default:
                    super.handleMessage(msg);
            }
        }
    };
	
	private void printByte(byte[] r_buf, int len) {
		String s = new String();
		for(int i = 0; i < len; i++){
			s += r_buf[i] + ",";
		}
		log("service ::" + s);
		
	}

	private void log(Object o) {
		Log.d(TAG, "" + o);
	}
}

- 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);
	}
}

完整源码下载,挣点分数,哈哈

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值