我在Android应用中使用长轮询实现聊天应用程序时遇到问题。搜索新邮件工作正常,它在HttpUrlConnection
的异步任务中运行。问题在于发送消息。我还使用HttpUrlConnection
的另一个异步任务,但根据我打印的日志,只有在搜索新消息完成后,即在30秒的长轮询之后才会发送消息。
这是我正在使用的异步尝试:
HttpPost.java
package com.roscosoft.taxifast;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
/**
* Created by titin on 7/12/16.
*/
public class HttpPost extends AsyncTask<Void, Void, Boolean> {
Exception error;
public interface HttpPostInterface {
void termino(JSONObject obj);
void cancelo(String error);
}
public static String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for(Map.Entry<String, String> entry : params.entrySet()){
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
private StringBuilder response;
private String postDataString;
private String url;
private HttpPostInterface delegate;
private int timeout;
HttpPost(String urlx, String postDataStringx, HttpPostInterface del) {
url = urlx;
postDataString = postDataStringx;
delegate = del;
timeout = 30000;
}
HttpPost(String urlx, String postDataStringx, HttpPostInterface del, int timeoutx) {
url = urlx;
postDataString = postDataStringx;
delegate = del;
timeout = timeoutx;
}
@Override
protected Boolean doInBackground(Void... params) {
response = new StringBuilder();
URL urlc = null;
HttpURLConnection con = null;
try{
urlc = new URL(url);
}catch (MalformedURLException e){
Log.i("rosco", e.getMessage());
error = e;
return false;
}
try {
con = (HttpURLConnection)urlc.openConnection();
con.setReadTimeout(timeout);
con.setConnectTimeout(timeout);
con.setRequestMethod("POST");
con.setDoInput(true);
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(postDataString);
writer.flush();
writer.close();
os.close();
int responseCode = con.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK){
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
while ((line = br.readLine()) != null){
response.append(line);
}
}else{
error = new Exception("Error:"+responseCode);
return false;
}
} catch (Exception e) {
Log.i("rosco", "Hubo un error al hacer el request:"+e.getMessage());
error = e;
return false;
}finally {
con.disconnect();
}
return true;
}
@Override
protected void onPostExecute(final Boolean success) {
if (success) {
try{
if (response.toString().length() == 0){
if(delegate != null) delegate.cancelo("No hay respuesta del servidor");
}else{
//Log.i("rosco", response.toString()); // solo en desarrollo
}
JSONObject obj = new JSONObject(response.toString());
if(delegate != null) delegate.termino(obj);
}catch (JSONException e){
Log.i("rosco", "Json malformado:"+e.getMessage()+":\n"+response.toString());
if(delegate != null) delegate.cancelo(response.toString());
}
} else {
if(delegate != null) delegate.cancelo(error.getMessage());
}
}
@Override
protected void onCancelled() {
if(delegate != null) {
if (error == null)
delegate.cancelo("Se cancelo el request");
else
delegate.cancelo(error.getMessage());
}
}
}
Web服务是用PHP制作的,服务器可能会等待第一个连接完成以接受发送消息&#39;连接? 如果是这样,你知道如何解决它吗? 非常感谢提前。
答案 0 :(得分:1)
您需要使用THREAD_POOL_EXECUTOR
来执行AsyncTask。默认实现使用在单个线程上运行的串行执行程序
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
答案 1 :(得分:0)
所有AsyncTasks都在单线程中执行序列。虽然第一个AsyncTask没有完成,但第二个任务将无法启动。我(和很多开发人员)不建议使用AsyncTask。 替代方案:来自java.util.concurrent的Java线程,Rx,Executors等。 或者使用Square的Retrofit库来执行异步http请求。