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