我们知道,Android上常见的多进程通讯有以下几种:
AIDL 进程通信接口
Binder接口
Messenger通信框架
BroadCastReciever 广播
ContentObserver/ContentProvider
FileObserver(http://blog.csdn.net/happy_6678/article/details/7095012)
网络,(http网络中转,rpc,dwr,jms,xmpp)
Intent通信
当然,我们还有另一种方案
LocalSocket 是Unix进程通信的基础
认识几个常用的函数:
客户端:
LocalSocket客户端使用,创建套接字
LocalSocketAddress 套接字地址,其实就是文件描述符(主要是服务器的地址,当然也可以客户端自个绑定地址)
setSoTimeout设置超时
connect客户端主动向服务端请求连接
服务端:
LocalServerSocket服务端使用,创建套接字同时指定文件描述符
accept等待客户端连接(阻塞)
共同:
getInputStream获取套接字输入流
getOutputStream获取套接字输出流
close关闭套接字,客户服务都需要
关于套接字的通信直接就是对java输入输出流的操作了,但是有一点很重要:对于套接字获取的各种输入或者输出流,如果调用close函数关闭了对应的流,那么套接字也会自动关闭了,再次对其获取输入输出流的时候会提示 socket not creat 。这点不同于C下socket的 shutdown函数,我也因为这折腾了很久。
下面不多说上代码,我对在客户端对其做了小小的封装:
class ClientConnect {
private static final String TAG = "ClientConnect";
private static final String name = "com.repackaging.localsocket";
private LocalSocket Client = null;
private PrintWriter os = null;
private BufferedReader is = null;
private int timeout = 30000;
public void connect(){
try {
Client = new LocalSocket();
Client.connect(new LocalSocketAddress(name));
Client.setSoTimeout(timeout);
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String[] data) {
try {
os = new PrintWriter(Client.getOutputStream());
for(int i = 0 ; i
os.println(data[0]);
}
os.println(FLAG);
os.flush();
Log.d(TAG,"send");
} catch (IOException e) {
e.printStackTrace();
}
}
public String recv() {
Log.d(TAG,"recv");
String result = null;
try {
is = new BufferedReader(new InputStreamReader(Client.getInputStream()));
result = is.readLine();
Log.d(TAG, result);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return result;
}
public void close() {
try {
is.close();
os.close();
Client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
由于是在Android代码上使用,为了防止ANR,对于服务端,肯定是放到线程中去的。对于阻塞模式的客户端(recv等函数),也必须放在线程中。
服务端线程:
class ServerThread implements Runnable {
@Override
public void run() {
LocalServerSocket server = null;
BufferedReader mBufferedReader = null;
PrintWriter os = null;
LocalSocket connect = null;
String readString =null;
try {
server = new LocalServerSocket("com.repackaging.localsocket");
while (true) {
connect = server.accept();
Credentials cre = connect.getPeerCredentials();
Log.i(TAG,"accept socket uid:"+cre.getUid());
mBufferedReader = new BufferedReader(new InputStreamReader
(connect.getInputStream()));
while((readString=mBufferedReader.readLine())!=null){
if(readString.equals("finish")) break;
Log.d(TAG,readString);
}
os = new PrintWriter(connect.getOutputStream());
os.println("allow");
os.flush();
Log.d(TAG,"send allow");
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
mBufferedReader.close();
os.close();
connect.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}