MemoryFile匿名共享内存简单案例

MemoryFile:匿名共享内存
用匿名共享内存来实现进程间内存共享
Binder不能传递太大的数据。最大通常限制为1M。

通过文件来跨进程传递数据,但是普通文件的效率太低,更优的方法是通过MemoryFile传递。

/**服务端*/
public class MainActivity extends Activity {

	
	private MemoryFile mMemoryFile;
	private final int MEMORY_SIZE = 3133440 + 1;
	private byte[] buffer;
	Binder mBinder;
	private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
        	mBinder = (Binder) service;
        }
        
        public void onServiceDisconnected(ComponentName className) {
        	mBinder = null;
        }
    };
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        Intent it = new Intent(this, MainService.class);
        startService(it);
        bindService(it, mConnection, Context.BIND_AUTO_CREATE);
        
        try {
        	// 参数1文件名,可为null,参数2文件长度
			mMemoryFile = new MemoryFile("test", MEMORY_SIZE);
		} catch (IOException e) {
			e.printStackTrace();
		}
       
    }
    android.os.Parcel data = android.os.Parcel.obtain();
	android.os.Parcel reply = android.os.Parcel.obtain();
    public void write(View v){
    	EditText et = (EditText) findViewById(R.id.et);
    	buffer = et.getText().toString().getBytes();
    	try {
    		// 写一次 , 读取数据后 数据会被清空
    		// 持续写,不读,数据不会清空,注意数据覆盖(offset值)
			mMemoryFile.writeBytes(buffer, 0, 0, buffer.length);
			 Method getFileDescriptorMethod = mMemoryFile.getClass().getDeclaredMethod("getFileDescriptor");
             if(getFileDescriptorMethod != null){
                 FileDescriptor fileDescriptor = (FileDescriptor) getFileDescriptorMethod.invoke(mMemoryFile);
                 // 序列化,才可传送
                 ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(fileDescriptor);
                 if(mBinder!=null){
                	//data.writeParcelable(pfd, 0);
                	// 或者
                	data.writeFileDescriptor(fileDescriptor);
                	 mBinder.transact(0, data, reply, 0);
                 }
             }
		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(this, "写失败", 0).show();
		}
    }
    
    @Override
    protected void onDestroy() {
    	if(mMemoryFile != null){
            mMemoryFile.close();
            mMemoryFile = null;
        }
    	unbindService(mConnection);
    	mConnection = null;
    	super.onDestroy();
    }
}
public class MainService extends Service {

	ParcelFileDescriptor pfd;
	
	@Override
	public IBinder onBind(Intent arg0) {
		return new MyBinder();
	}
	
	
	class MyBinder extends Binder {
		@Override
		protected boolean onTransact(int code, Parcel data, Parcel reply,int flags) throws RemoteException {
			switch (code) {
			case 0:
				//pfd = data.readParcelable(null);
				// 或者
				pfd = data.readFileDescriptor();
				break;
			case 1:
				//reply.writeParcelable(pfd,0);
				// 或者
				reply.writeFileDescriptor(pfd.getFileDescriptor());
				break;

			default:
				break;
			}
			// 
			return true;
		}
	}

}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    >

    <EditText 
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="写入"
        android:onClick="write"
         />

</LinearLayout>
/**客户端*/
public class MainActivity extends Activity {

	private final int MEMORY_SIZE = 3133440 + 1;
	private byte[] buffer = new byte[20];

	IBinder mBinder;
	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			// 非服务创建进程,获取的Binder只是一个代理Binder对象,不能直接转换
			// mBinder = (Binder) service;
			mBinder = service;
		}

		public void onServiceDisconnected(ComponentName className) {
			mBinder = null;
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.fragment_main);

		Intent it = new Intent("com.xzc.memoryfilewrite.MainService");
		startService(it);
		bindService(it, mConnection, Context.BIND_AUTO_CREATE);

	}

	public void read(View v) {
		TextView tv = (TextView) findViewById(R.id.tv);
		FileInputStream fi=null;
		FileDescriptor fileDescriptor=null;
		try {
			if (mBinder != null) {
				android.os.Parcel data = android.os.Parcel.obtain();
				android.os.Parcel reply = android.os.Parcel.obtain();
				mBinder.transact(1, data, reply, 0);
				//ParcelFileDescriptor pfd = reply.readParcelable(null);
				// 或者
				ParcelFileDescriptor pfd = reply.readFileDescriptor();
				if(pfd==null){
					buffer = "ParcelFileDescriptor 空指针".getBytes();
					tv.setText(new String(buffer));
					return;
				}
				fileDescriptor = pfd.getFileDescriptor();
				fi = new FileInputStream(fileDescriptor);
				fi.read(buffer);
			}
			
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(fileDescriptor!=null){
				try {
					fi.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		tv.setText(new String(buffer));
	}

	@Override
	protected void onDestroy() {
		unbindService(mConnection);
		mConnection = null;
		super.onDestroy();
	}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    >

    <Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="读取"
        android:onClick="read"
        />
    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="88"
         />

</LinearLayout>





猜你喜欢

转载自blog.csdn.net/qq_24451593/article/details/80514566
今日推荐