简介
android app是运行在java虚拟机上的一个进程,是android 设备与设备使用对象的交互对象,承接使用者的指令与转换这些指令到android设备。
由于android app实现一般是java语言,对设备的进行操作的是C NATIVE,java与c之间一般要进行一个交互过程。这里提供一个Java和C交互的方法:
localsocket。
在Unix域名空间创建一个套接字(非服务端)。
是对Linux中Socket进行了封装,采用JNI方式调用,实现进程间通信。
具体就是Native层Server和Framework层Client之间进行通信,或在各 层次中能使用Client/Server模式实现通信。
实现
app
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.util.Log;
public class socket_connect {
private final String SOCKET_NAME = "socket_test0";
private LocalSocket client;
private LocalSocketAddress address;
private boolean isConnected = false;
private int connetTime = 1;
public socket_connect() {
client = new LocalSocket();
address = new LocalSocketAddress(SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED);
new ConnectSocketThread().start();
}
public String sendMsg(String msg) {
if (!isConnected) {
return "Connect fail";
}
try {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream());
out.println(msg);
out.flush();
return in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return "Nothing return";
}
private class ConnectSocketThread extends Thread {
@Override
public void run() {
while (!isConnected && connetTime <= 10) {
try {
sleep(1000);
Log.i("SocketClient","Try to connect socket;ConnectTime:"+connetTime);
client.connect(address);
isConnected = true;
} catch (Exception e) {
connetTime++;
isConnected = false;
Log.i("SocketClient","Connect fai:" + e.toString());
}
}
}
}
public void closeSocket() {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Native
define SOCKET_NAME "socket_test0"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <cutils/sockets.h>
#include <utils/Log.h>
#include <android/log.h>
int main(){
char log[200];
int connect_number = 6;
int fdListen = -1, new_fd = -1;
int ret;
struct sockaddr_un peeraddr;
socklen_t socklen = sizeof (peeraddr);
int numbytes ;
char buff[256];
fdListen = android_get_control_socket(SOCKET_NAME);
if (fdListen < 0) {
sprintf(log,"Failed to get socket '" SOCKET_NAME "' errno:%d", errno);
__android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log);
exit(-1);
}
ret = listen(fdListen, connect_number);
sprintf(log,"Listen result %d",ret);
__android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log);
if (ret < 0) {
perror("listen");
exit(-1);
}
new_fd = accept(fdListen, (struct sockaddr *) &peeraddr, &socklen);
sprintf(log,"Accept_fd %d",new_fd);
__android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log);
if (new_fd < 0 ) {
sprintf(log,"%d",errno);
__android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log);
perror("accept error");
exit(-1);
}
while(1){
__android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI","Waiting for receive");
if((numbytes = recv(new_fd,buff,sizeof(buff),0))==-1){
sprintf(log,"%d",errno);
__android_log_write(ANDROID_LOG_DEBUG,"FTM_JNI",log);
perror("recv");
continue;
}
if(send(new_fd,buff,strlen(buff),0)==-1)
{
perror("send");
close(new_fd);
exit(0);
}
}
close(new_fd);
close(fdListen);
return 0;
}
创建socket套接字
在android init.rc中加入启动native 程序的命令和创建套接字的命
service socket_test /system/bin/socket_test
class main
socket socket_test0 stream 600 system system