我们都知道intent是Android各组件之间通信的核心。对于简单的的进程内或进程间通信,intent基本能够满足了。但是一些稍微复杂些的交互(如一些随时需要的控制请求)等,仅仅依靠intent这种消息机制实现便显得力不从心了。关于Android进程间的通信,大家普遍用的还是AIDL,但它只适用于 Activity与Service之间的通信,不免有一定的限制。而我这次主要介绍的是LocalSocket。

之前关于套接字的操作都是在C上使用的,虽然java封装了很多细节,但用起来不免有些不习惯。C虽然繁琐却使得开发者更为了解其具体细节。而本文也旨在记录自己毕设中用到技术或碰到的问题,以java角度出发。先看看TCP socket通信的模型,LocalSocket也一样只不过是没有跨越网络边界:

认识几个常用的函数:

客户端:

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 < data.length ; 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();}}}


调用代码:

ClientConnect client = new ClientConnect();client.connect();client.send(data);result = client.recv();client.close();


由于是在Android代码上使用,为了防止ANR,对于服务端,肯定是放到线程中去的。对于阻塞模式的客户端(recv等函数),也必须放在线程中。

服务端线程:

class ServerThread implements Runnable {@Overridepublic 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();}}}}

以上就是简单的LocalSocket模型。在处理交互方面还是很方便的,尽量都放到线程中去执行。


更多相关文章

  1. Android信息推送技术简要分析
  2. 一篇读懂:Android/iOS手机如何通过音频接口(耳机孔)与外设通信
  3. 在Android系统使用socket在Java层和native之间数据通信
  4. Android微信支付彻底扫坑
  5. Android中实现native服务利用binder与应用通信
  6. Android 消息推送
  7. WebSocket实现Android客户端之间的简单通讯
  8. Android(安卓)手机蓝牙 (普通蓝牙篇)
  9. Android-小巫新闻客户端底部菜单切换实现

随机推荐

  1. Android(安卓)插件化 动态升级
  2. Android性能调优总结
  3. 简析Android对Linux内核的改动
  4. Android中ContentProvider详解
  5. Android电话拨打流程源码分析
  6. Android流媒体播放器
  7. Android(安卓)适配---notification led
  8. android中android:layout_gravity和andro
  9. Android程序员必看之Android六大优势
  10. Android(安卓)音频 OpenSL ES PCM数据播