Android笔记--共享内存

       这一节了解一下共享内存,Android系统实现了一个匿名共享内存,用来在应用程序之间共享数据。匿名共享内存与传统的Linux系统实现的共享内存一样,都是基于内核提供的临时文件系统tmpfs实现的。但是前者对内存块进行了更为精细化的管理。应用程序可以动态地将一块匿名共享内存划分为若干个小块,当这些小块内存不再需要使用时,它们就可以被内存管理系统回收。匿名共享内存系统是以Ashmem驱动程序为基础的,系统中所有的匿名共享内存都由Ashmem驱动程序负责分配和管理。  在应用程序框架层中,是通过一个Java类MemoryFile来使用匿名共享内存;

MemoryFile
MemoryFile是对SharedMemory的包装,官方推荐使用SharedMemory

SharedMemory
SharedMemory只能经过调用SharedMemory.create静态方法或者经过Parcel反序列化的方式进行建立。函数由于SharedMemory类实现了Parcelable,因此能够经过binder跨进程传输。

简单看个栗子:

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.MemoryFile;
import android.os.Parcel;
import android.os.RemoteException;
import androidx.appcompat.app.AppCompatActivity;
import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MainActivity extends AppCompatActivity {

    ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            try {
                String str = "来自发送端的数据";
                MemoryFile memoryFile = new MemoryFile("Asheme", str.getBytes().length);
                memoryFile.writeBytes(str.getBytes(), 0, 0, str.getBytes().length);
                Method method = MemoryFile.class.getDeclaredMethod("getFileDescriptor");
                FileDescriptor des = (FileDescriptor) method.invoke(memoryFile);
                Parcel data = Parcel.obtain();
                data.writeFileDescriptor(des);
                data.writeInt(str.getBytes().length);
                Parcel reply = Parcel.obtain();
                service.transact(12345, data, reply, 0);
            } catch (RemoteException | IOException | NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, AshmemService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
    }
}
import static java.nio.charset.StandardCharsets.UTF_8;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class AshmemService extends Service {
    public AshmemService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        return new AshmemBinder();
    }

    class AshmemBinder extends Binder {
        @Override
        protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
            if (code == 12345) {
                try {
                    ParcelFileDescriptor pfd = data.readFileDescriptor();
                    int size = data.readInt();
                    InputStream inputStream = new FileInputStream(pfd.getFileDescriptor());
                    byte[] bytes = new byte[1024];
                    inputStream.read(bytes, 0, size);
                    String message = new String(bytes, 0, size, UTF_8);
                    Log.i("LJT", "接受到的数据为:" + message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return true;
            } else {
                return super.onTransact(code, data, reply, flags);
            }
        }
    }
}

输出:

接受到的数据为:来自发送端的数据

你可能感兴趣的:(Android基础,android,android)