有了Binder进程间通信接口之后,接下来就是要在Server端实现一个本地服务了。这里,Server端实现的本地服务名为MemoryService,实现在src/shy/luo/ashmem/MemoryService.java文件中:
- package shy.luo.ashmem;
-
- import java.io.FileDescriptor;
- import java.io.IOException;
-
- import android.os.Parcel;
- import android.os.MemoryFile;
- import android.os.ParcelFileDescriptor;
- import android.util.Log;
-
- public class MemoryService extends IMemoryService.Stub {
- private final static String LOG_TAG = "shy.luo.ashmem.MemoryService";
- private MemoryFile file = null;
-
- public MemoryService() {
- try {
- file = new MemoryFile("Ashmem", 4);
- setValue(0);
- }
- catch(IOException ex) {
- Log.i(LOG_TAG, "Failed to create memory file.");
- ex.printStackTrace();
- }
- }
-
- public ParcelFileDescriptor getFileDescriptor() {
- Log.i(LOG_TAG, "Get File Descriptor.");
-
- ParcelFileDescriptor pfd = null;
-
- try {
- pfd = file.getParcelFileDescriptor();
- } catch(IOException ex) {
- Log.i(LOG_TAG, "Failed to get file descriptor.");
- ex.printStackTrace();
- }
-
- return pfd;
- }
-
- public void setValue(int val) {
- if(file == null) {
- return;
- }
-
- byte[] buffer = new byte[4];
- buffer[0] = (byte)((val >>> 24) & 0xFF);
- buffer[1] = (byte)((val >>> 16) & 0xFF);
- buffer[2] = (byte)((val >>> 8) & 0xFF);
- buffer[3] = (byte)(val & 0xFF);
-
- try {
- file.writeBytes(buffer, 0, 0, 4);
- Log.i(LOG_TAG, "Set value " + val + " to memory file. ");
- }
- catch(IOException ex) {
- Log.i(LOG_TAG, "Failed to write bytes to memory file.");
- ex.printStackTrace();
- }
- }
- }
- package shy.luo.ashmem;
-
- import java.io.FileDescriptor;
- import java.io.IOException;
-
- import android.os.Parcel;
- import android.os.MemoryFile;
- import android.os.ParcelFileDescriptor;
- import android.util.Log;
-
- public class MemoryService extends IMemoryService.Stub {
- private final static String LOG_TAG = "shy.luo.ashmem.MemoryService";
- private MemoryFile file = null;
-
- public MemoryService() {
- try {
- file = new MemoryFile("Ashmem", 4);
- setValue(0);
- }
- catch(IOException ex) {
- Log.i(LOG_TAG, "Failed to create memory file.");
- ex.printStackTrace();
- }
- }
-
- public ParcelFileDescriptor getFileDescriptor() {
- Log.i(LOG_TAG, "Get File Descriptor.");
-
- ParcelFileDescriptor pfd = null;
-
- try {
- pfd = file.getParcelFileDescriptor();
- } catch(IOException ex) {
- Log.i(LOG_TAG, "Failed to get file descriptor.");
- ex.printStackTrace();
- }
-
- return pfd;
- }
-
- public void setValue(int val) {
- if(file == null) {
- return;
- }
-
- byte[] buffer = new byte[4];
- buffer[0] = (byte)((val >>> 24) & 0xFF);
- buffer[1] = (byte)((val >>> 16) & 0xFF);
- buffer[2] = (byte)((val >>> 8) & 0xFF);
- buffer[3] = (byte)(val & 0xFF);
-
- try {
- file.writeBytes(buffer, 0, 0, 4);
- Log.i(LOG_TAG, "Set value " + val + " to memory file. ");
- }
- catch(IOException ex) {
- Log.i(LOG_TAG, "Failed to write bytes to memory file.");
- ex.printStackTrace();
- }
- }
- }
package shy.luo.ashmem;
import java.io.FileDescriptor;
import java.io.IOException;
import android.os.Parcel;
import android.os.MemoryFile;
import android.os.ParcelFileDescriptor;
import android.util.Log;
public class MemoryService extends IMemoryService.Stub {
private final static String LOG_TAG = "shy.luo.ashmem.MemoryService";
private MemoryFile file = null;
public MemoryService() {
try {
file = new MemoryFile("Ashmem", 4);
setValue(0);
}
catch(IOException ex) {
Log.i(LOG_TAG, "Failed to create memory file.");
ex.printStackTrace();
}
}
public ParcelFileDescriptor getFileDescriptor() {
Log.i(LOG_TAG, "Get File Descriptor.");
ParcelFileDescriptor pfd = null;
try {
pfd = file.getParcelFileDescriptor();
} catch(IOException ex) {
Log.i(LOG_TAG, "Failed to get file descriptor.");
ex.printStackTrace();
}
return pfd;
}
public void setValue(int val) {
if(file == null) {
return;
}
byte[] buffer = new byte[4];
buffer[0] = (byte)((val >>> 24) & 0xFF);
buffer[1] = (byte)((val >>> 16) & 0xFF);
buffer[2] = (byte)((val >>> 8) & 0xFF);
buffer[3] = (byte)(val & 0xFF);
try {
file.writeBytes(buffer, 0, 0, 4);
Log.i(LOG_TAG, "Set value " + val + " to memory file. ");
}
catch(IOException ex) {
Log.i(LOG_TAG, "Failed to write bytes to memory file.");
ex.printStackTrace();
}
}
} 注意,这里的MemoryService类实现了IMemoryService.Stub类,表示这是一个Binder服务的本地实现。在构造函数中,通过指定文件名和文件大小来创建了一个匿名共享内存文件,即创建MemoryFile的一个实例,并保存在类成员变量file中。这个匿名共享内存文件名为"Ashmem",大小为4个节字,刚好容纳一个整数,我们这里举的例子就是要说明如果创建一个匿名共享内存来在两个进程间实现共享一个整数了。当然,在实际应用中,可以根据需要创建合适大小的共享内存来共享有意义的数据。
这里还实现了IMemoryService.Stub的两个接口getFileDescriptor和setVal,一个用来获取匿名共享内存文件的文件描述符,一个来往匿名共享内存文件中写入一个整数,其中,接口getFileDescriptor的返回值是一个ParcelFileDescriptor。在Java中,是用FileDescriptor类来表示一个文件描述符的,而ParcelFileDescriptor是用来序列化FileDescriptor的,以便在进程间调用时传输。
定义好本地服务好,就要定义一个Server来启动这个服务了。这里定义的Server实现在src/shy/luo/ashmem/Server.java文件中:
- package shy.luo.ashmem;
-
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.util.Log;
- import android.os.ServiceManager;
-
- public class Server extends Service {
- private final static String LOG_TAG = "shy.luo.ashmem.Server";
-
- private MemoryService memoryService = null;
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- @Override
- public void onCreate() {
- Log.i(LOG_TAG, "Create Memory Service...");
-
- memoryService = new MemoryService();
-
- try {
- ServiceManager.addService("AnonymousSharedMemory", memoryService);
- Log.i(LOG_TAG, "Succeed to add memory service.");
- } catch (RuntimeException ex) {
- Log.i(LOG_TAG, "Failed to add Memory Service.");
- ex.printStackTrace();
- }
-
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- Log.i(LOG_TAG, "Start Memory Service.");
- }
-
- @Override
- public void onDestroy() {
- Log.i(LOG_TAG, "Destroy Memory Service.");
- }
- }
- package shy.luo.ashmem;
-
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.util.Log;
- import android.os.ServiceManager;
-
- public class Server extends Service {
- private final static String LOG_TAG = "shy.luo.ashmem.Server";
-
- private MemoryService memoryService = null;
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- @Override
- public void onCreate() {
- Log.i(LOG_TAG, "Create Memory Service...");
-
- memoryService = new MemoryService();
-
- try {
- ServiceManager.addService("AnonymousSharedMemory", memoryService);
- Log.i(LOG_TAG, "Succeed to add memory service.");
- } catch (RuntimeException ex) {
- Log.i(LOG_TAG, "Failed to add Memory Service.");
- ex.printStackTrace();
- }
-
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- Log.i(LOG_TAG, "Start Memory Service.");
- }
-
- @Override
- public void onDestroy() {
- Log.i(LOG_TAG, "Destroy Memory Service.");
- }
- }
package shy.luo.ashmem;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.os.ServiceManager;
public class Server extends Service {
private final static String LOG_TAG = "shy.luo.ashmem.Server";
private MemoryService memoryService = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Log.i(LOG_TAG, "Create Memory Service...");
memoryService = new MemoryService();
try {
ServiceManager.addService("AnonymousSharedMemory", memoryService);
Log.i(LOG_TAG, "Succeed to add memory service.");
} catch (RuntimeException ex) {
Log.i(LOG_TAG, "Failed to add Memory Service.");
ex.printStackTrace();
}
}
@Override
public void onStart(Intent intent, int startId) {
Log.i(LOG_TAG, "Start Memory Service.");
}
@Override
public void onDestroy() {
Log.i(LOG_TAG, "Destroy Memory Service.");
}
} 这个Server继承了Android系统应用程序框架层提供的Service类,当它被启动时,运行在一个独立的进程中。当这个Server被启动时,它的onCreate函数就会被调用,然后它就通过ServiceManager的addService接口来添加MemoryService了:
- memoryService = new MemoryService();
-
- try {
- ServiceManager.addService("AnonymousSharedMemory", memoryService);
- Log.i(LOG_TAG, "Succeed to add memory service.");
- } catch (RuntimeException ex) {
- Log.i(LOG_TAG, "Failed to add Memory Service.");
- ex.printStackTrace();
- }
- memoryService = new MemoryService();
-
- try {
- ServiceManager.addService("AnonymousSharedMemory", memoryService);
- Log.i(LOG_TAG, "Succeed to add memory service.");
- } catch (RuntimeException ex) {
- Log.i(LOG_TAG, "Failed to add Memory Service.");
- ex.printStackTrace();
- }
memoryService = new MemoryService();
try {
ServiceManager.addService("AnonymousSharedMemory", memoryService);
Log.i(LOG_TAG, "Succeed to add memory service.");
} catch (RuntimeException ex) {
Log.i(LOG_TAG, "Failed to add Memory Service.");
ex.printStackTrace();
} 这样,当这个Server成功启动了,Client就可以通过ServiceManager的getService接口来获取这个MemoryService了。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/13164110/viewspace-747973/
,如需转载,请注明出处,否则将追究法律责任。