问题
I have some data which will be sent from an Android app to a server via http(s). It needs to be sent in-order.
Does there already exist a way of queuing http requests (for the same server) and retrying them until they complete (not necessarily succeed)?
My problem is that http requests may fail if there is not network coverage. There should be some form of exponential back-off, or a listener (for network reconnection) to prompt retrying the head of the queue.
I can write this myself, but I want to check that I'm not re-inventing the wheel.
回答1:
There are several options to do it:
Volley:
RequestQueue queue = Volley.newRequestQueue(ctx); // ctx is the context
StringRequest req = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String data) {
// We handle the response
}
},
new Response.ErrorListener() {
@Override
// handle response
}
);
queue.add(req);
OkHttp:
OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
// Handle error
}
@Override
public void onResponse(Response response) throws IOException {
//handle response
}
});
Or you can use a counter in your requests and let the server order them. If you are interested to have more details about Android Http libraries i wrote a post recentely. Give a look here
回答2:
I am using this method for post https I am successfully done for all conditions.
private class AysncTask extends AsyncTask<Void,Void,Void>
{
private ProgressDialog regDialog=null;
@Override
protected void onPreExecute()
{
super.onPreExecute();
regDialog=new ProgressDialog(this);
regDialog.setTitle(getResources().getString(R.string.app_name));
regDialog.setMessage(getResources().getString(R.string.app_pleasewait));
regDialog.setIndeterminate(true);
regDialog.setCancelable(true);
regDialog.show();
}
@Override
protected Void doInBackground(Void... params) {
try
{
new Thread(new Runnable() {
@Override
public void run() {
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("param1",
paramvalue));
postParameters.add(new BasicNameValuePair("param2",
paramvalue));
String response = null;
try {
response = SimpleHttpClient
.executeHttpPost("url.php",
postParameters);
res = response.toString();
return res;
} catch (Exception e) {
e.printStackTrace();
errorMsg = e.getMessage();
}
}
}).start();
try {
Thread.sleep(3000);
// error.setText(resp);
if (null != errorMsg && !errorMsg.isEmpty()) {
}
} catch (Exception e) {
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
if(regDialog!=null)
{
regDialog.dismiss();
//do you code here you want
}
// do what u do
}
SimpleHttpClient.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
public class SimpleHttpClient {
/** The time it takes for our client to timeout */
public static final int HTTP_TIMEOUT = 30 * 1000; // milliseconds
/** Single instance of our HttpClient */
private static HttpClient mHttpClient;
/**
* Get our single instance of our HttpClient object.
*
* @return an HttpClient object with connection parameters set
*/
private static HttpClient getHttpClient() {
if (mHttpClient == null) {
mHttpClient = new DefaultHttpClient();
final HttpParams params = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, HTTP_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
}
return mHttpClient;
}
public static String executeHttpPost(String url, ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String result = sb.toString();
return result;
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String executeHttpatch(String url, ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String result = sb.toString();
return result;
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Performs an HTTP GET request to the specified url.
*
* @param url The web address to post the request to
* @return The result of the request
* @throws Exception
*/
public static String executeHttpGet(String url) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(url));
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String result = sb.toString();
return result;
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
来源:https://stackoverflow.com/questions/38390463/retry-https-posts-until-they-succeed-on-android