使用 a LocalSocket
,但要小心,因为存在安全隐患。
LocalSocket
是用于处理 Unix 域套接字的 Android API。域套接字类似于 TCP/IP 套接字,只是它们只存在于设备上,不能用于跨网络通信。
您的问题的一个简单但不安全的解决方案如下:
// Create a unique name for the socket.
String name = "your.package.name-" + UUID.randomUUID();
// Bind a server to the socket.
final LocalServerSocket server = new LocalServerSocket(name);
// Connect a client to the socket.
LocalSocket client = new LocalSocket(LocalSocket.SOCKET_STREAM);
client.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT));
// Start a thread to read from the server socket.
new Thread(new Runnable {
@Override
public void run() {
LocalSocket socket = server.accept();
// To read data sent by the client, read from socket.getInputStream().
// To send data to the client, write to socket.getOutputStream().
// After you are done you will need to call socket.close().
}
}).start();
// Get the FileDescriptor associated with the client.
// You can use this FileDescriptor to write data to and/or read data
// sent from the server.
FileDescriptor fileDescriptor = client.getFileDescriptor();
// After you are done you will need to call server.close() and client.close().
这会在抽象套接字命名空间中创建一个套接字。这是不安全的,因为域套接字是系统范围的,并且抽象命名空间中的套接字不受任何权限系统的限制。连接或绑定到抽象命名空间中的名称的唯一要求是知道名称,并且您的应用程序使用的套接字名称很容易被攻击者通过反编译发现。另一个应用程序也有可能意外使用相同的套接字名称。所以另一个应用程序可能会拦截你的数据,或者通过套接字发送意外数据,这是很难防范的。
一个更好但更复杂的解决方案是在文件系统命名空间中创建一个套接字。执行此操作的 API 非常奇怪,但可以通过以下方式实现:
// Create a unique name for the socket in your app's private data area.
// Note this example creates a file named like socket-xxxx in the root of
// your app's private data area. You might want to put it in a subdirectory.
String name = context
.getFileStreamPath("socket-" + UUID.randomUUID())
.getAbsolutePath();
LocalSocketAddress address = new LocalSocketAddress(name, LocalSocketAddress.Namespace.FILESYSTEM);
// Bind a server to the socket.
LocalSocket server = new LocalSocket(LocalSocket.SOCKET_STREAM);
server.bind(address);
final LocalServerSocket serverWrapper = new LocalServerSocket(server.getFileDescriptor());
// Connect a client to the socket.
LocalSocket client = new LocalSocket(LocalSocket.SOCKET_STREAM);
client.connect(address);
// Start a thread to read from the server socket.
new Thread(new Runnable {
@Override
public void run() {
LocalSocket socket = serverWrapper.accept();
// To read data sent by the client, read from socket.getInputStream().
// To send data to the client, write to socket.getOutputStream().
// After you are done you will need to call socket.close() and
// serverWrapper.close().
}
}).start();
// Get the FileDescriptor associated with the client.
// You can use this FileDescriptor to write data to and/or read data
// sent from the server.
FileDescriptor fileDescriptor = client.getFileDescriptor();
// After you are done you will need to call server.close() and client.close().
这确实在文件系统上创建了一个文件,但是通过套接字的数据都没有写入磁盘,它完全在内存中。该文件只是一个代表套接字的名称,类似于/dev
代表设备的文件。因为套接字是通过文件系统访问的,它受制于通常的文件系统权限,所以很容易通过将套接字放在应用程序的私有数据区来限制对套接字的访问。
由于这种技术会在文件系统上创建一个文件,因此最好在完成后删除该文件,并且可能每隔一段时间检查和清理旧套接字,以防您的应用程序崩溃并留下旧文件躺着。