2017-04-11 40 views
0

我在使用长轮询在Android应用中实现聊天应用程序时遇到问题。新邮件的搜索工作正常,它运行在异步任务HttpUrlConnection。问题在于发送消息。我还使用另一个异步任务HttpUrlConnection,但根据我打印的日志,只有在搜索新消息完成后,即在长轮询30秒后才发送。 下面是我使用的异步TAST:与长轮询的Android聊天

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做是有可能,对于到结束第一连接服务器等待接受'发送消息'连接? 如果是这样,你有任何想法如何解决它? 非常感谢。

+0

如果没有关于服务器实现的更多信息,这可能无法应答。 –

回答

0

您需要使用THREAD_POOL_EXECUTOR来执行AsyncTask。默认实现使用在单个线程上运行的串行执行程序

new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
+0

谢谢你,这没有诀窍:) –

0

所有AsyncTasks在单线程中执行序列。虽然第一个AsyncTask没有完成,但第二个任务不会启动。我(和很多开发人员)不推荐使用AsyncTask。 替代方案:Java线程,Rx,java.util.concurrent的执行程序等。 或者使用Square的Retrofit库来执行异步http请求。

+0

谢谢你,这是问题:) –