您的位置:首页 > 移动开发 > Android开发

android LocalSocket的使用

2017-03-10 14:50 1631 查看

需求:

在Activity与另外一个线程中的服务进行数据传递,之前只用的AIDL,但是这个传输是单向的,不满足项目的需求,后来发现了这个LocalSocket.于是自己摸索使用,网上的教程好多都是抄袭的看的不明白.

目标:一个进程与另一个进程间的通信.

1.首先来看配置

// 这个是我启动的服务,在单独的一个进程中执行 process这个属性不是很明白,请百度一下.
<service android:name=".LocalSocketService"
android:process=":server"/>
// 这是另外一种配置,我试了一下,这种方式也是可以实现的.
<service android:name=".LocalSocketService"
android:process="jin.frid.server"/>


2.Socket 原理我也不知道,我只知道这个是封装的C层的socket的实现.只是知道是一个双向传输的东西.

直接上服务端的代码

public class LocalSocketService extends Service {
public final static String TAG = "LocalSocketService";
public final static String ADDRESS = "/com/jin/kai100";
LocalSocket localSocket;
private LocalServerSocket localServerSocket;

@Override
public void onCreate() {
super.onCreate();
new Thread() {
@Override
public void run() {
try {
LocalServerSocket server = new LocalServerSocket(ADDRESS);

while (true) {
// 这个方法是阻塞的,有Client连接上来的时候,这里就会回调.
final LocalSocket receiver = server.accept();

new Thread() {
@Override
public void run() {
try {
Log.i(TAG, "server sender");
// 读取的是一个阻塞的过程,如果在这里不开一个线程的,那么会一直阻塞在这里,下面的代码得不到执行
InputStream input = receiver.getInputStream();
// 这里是读取的代码
int readed = 0;
byte[] bytes = new byte[1024];
// reading
while (readed != -1) {
// read next byte
readed = input.read(bytes);
Log.i(TAG, "server receive = " +new String(bytes, 0, readed));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();

if (receiver != null) {
// 这里是server发送信息,如果上面的读取阻塞了,就一直执行不到这里,所以上面开了线程处理.
OutputStream outputStream = receiver.getOutputStream();
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
Log.i(TAG, "server sender");
outputStream.write("haode".getBytes());
// 发送数据必须要在这里写入到输出流中,不然那边是接收不到
// 自己之前就在这里纠结了很久,因为自己之前用的LocalSocket的close()方法之后.另一边才能收到.我想了好久.我以为这个LocalSocket是一个类似短的服务连接.单次有效呢.后来发现自己理解错了
outputStream.flush();
}
}
}
} catch (IOException e) {
Log.e(getClass().getName(), e.getMessage());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {

return null;
}
}


3.另一个Activity的代码

public class MainActivity extends Activity {
private InputStream inputStream;
private OutputStream outputStream;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void button(View view) {
Intent intent = new Intent(getApplicationContext(), LocalSocketService.class);
startService(intent);
}

LocalSocket localSocket;
public void button2(View view) {

new Thread() {
@Override
public void run() {
localSocket = new LocalSocket();
try {
Log.i("MainActivity", "");
// 连接另外一个进程的Sever连接
// LocalSocketService.ADDRESS 这个是连接的地址,相当于每个连接标示符,你想连接到这个上
localSocket.connect(new LocalSocketAddress(LocalSocketService.ADDRESS));
Log.i("MainActivity", "localSocket.isConnected() = " +localSocket.isConnected());
// 设置接收的缓存空间的大小
localSocket.setReceiveBufferSize(500000);
localSocket.setSendBufferSize(500000);
// 获取连接的输入,输出流.
outputStream = localSocket.getOutputStream();
inputStream = localSocket.getInputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
// 这里是模拟想服务端发送信息
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
outputStream.write("client sender".getBytes());
Log.i("MainActivity", "client sender");
printWriter.flush();
}
// 这里启用线程,去读取,因为读取是阻塞操作,会造成问题的.
new Thread(){
@Override
public void run() {
try {
// 这里从本地服务读取信息
int readed = bufferedReader.read();
while (readed != -1) {
// read next byte
readed = bufferedReader.read();
Log.i("MainActivity", "clientRead=" + readed);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();

} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
/**
这里模拟客服端发送数据
**/
public void button3(View view) {
try {
if (localSocket != null) {
Log.i("MainActivity", "send message");

outputStream.write("haod".getBytes());
outputStream.flush();
}

} catch (IOException e) {
e.printStackTrace();
}
}
// 关闭连接
public void button4(View view) {
if (localSocket != null)
try {
localSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}


总结:LocalSocket 可以像Socket一样,可以双向发送接收.记得发送数据的时候要调用flush()方法,这里是我自己遇到的坑.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android LocalSocke