我实际上正在开发一个聊天安卓应用程序。
我对我创建的主题有疑问。基本上,我的客户端应用程序有一个连接到服务的活动。该服务负责客户端和服务器之间的通信。 (我也使用Asynctask)
我有两个主要方案:
我向服务器发送请求(刷新好友列表,添加好友,登录...),预计服务器的响应是没有问题的。
第二种情况是关于来自服务器的意外请求(当另一个人想要与您通信时)。为此,我在我的服务类中创建了一个这样的线程。
public void launchListener(){
Runnable SocketListener = new Runnable(){
public void run(){
String msg = "";
String[] msg_parts = {"","",""};
while(true){
try {
if (in.available() > 0){
msg = in.readLine();
msg_parts = msg.split(" ");
if (msg_parts[0].equals("CONNECTION")){
Log.d("SocketService", "Broadcasting message");
Intent intent = new Intent("ask.connection");
intent.putExtra("nickname", msg_parts[1]);
sendBroadcast(intent);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
Thread t = new Thread(SocketListener);
t.start();
}
问题是,该线程只等待“连接”,所以它也拦截了服务器的预期响应,我不知道为什么但这个线程冻结了我的应用程序。 这只是一种可能性,但也许是因为我也在其他地方使用 readLine ,它不起作用。
这里我使用readLine作为Asyntask中的预期响应:
protected String doInBackground(String... message) {
this.message = message[0];
this.out = service.getOut();
this.in = service.getIn();
try {
this.out.writeBytes(this.message + "\n");
this.out.flush();
} catch (IOException e) {
e.printStackTrace();
}
response = readLine(this.in);
return response;
}
我真的不知道为什么它不起作用,也许asynctask readLine首先读取响应,然后当我的线程读取它时,DataInputStream为空并且冻结。
无论如何,谢谢你的帮助!!
答案 0 :(得分:1)
如果(in.available() > 0){
评估为false
,则表示您正在浪费整个CPU核心,如果您在单核设备上运行,您的设备将会冻结。
使用Thread.sleep
缓解此问题并进入BlockingQueue
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
此外,您正在从两个线程访问您的服务,我希望它是线程安全的。
while(true){
try {
if (in.available() > 0) {
msg = in.readLine();
msg_parts = msg.split(" ");
if (msg_parts[0].equals("CONNECTION")){
Log.d("SocketService", "Broadcasting message");
Intent intent = new Intent("ask.connection");
intent.putExtra("nickname", msg_parts[1]);
sendBroadcast(intent);
}
} else {
Thread.sleep(100); // Or any sufficient delay.
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
break;
}
}