Android 不断尝试 POST 直到成功

标签 android post httpsurlconnection

我有一条 POST 消息,在给定的情况下我绝对必须在 Android 上发送,以至于我希望它继续尝试直到完成。我的理解是:

urlConnection.setConnectTimeout(0);

会继续尝试连接,直到连接成功,但实际发生的情况是 try block 失败,并且抛出了 UnknownHostException:

private class SendAlert extends AsyncTask<String, String, String> { 
protected String doInBackground(String... strings) {
      Log.d(TAG, "sendAlarm: sending alarm");
      String stringUrl = createUri();
      HttpsURLConnection urlConnection = null;
      BufferedReader reader = null;

      String postData = "";
      Log.d(TAG, "sendAlarm: apikey: " + apiKey);
         try{
            Log.d(TAG, "sendAlarm: trying");
            URL finalURL = new URL(stringUrl);              
            urlConnection = (HttpsURLConnection)finalURL.openConnection();
            urlConnection.setReadTimeout(10000);
            urlConnection.setConnectTimeout(0);
            urlConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            urlConnection.setRequestProperty("Accept","application/json");
            urlConnection.setRequestProperty("x-api-key",apiKey);
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);

            int responseCode = urlConnection.getResponseCode();
            Log.d(TAG, "doInBackground: response code = " + responseCode);

        }catch (MalformedURLException e) {
            e.printStackTrace();
            Log.d(TAG, "doInBackground: error 1 " + e.toString());
        }catch(UnknownHostException e){
            Log.d(TAG, "doInBackground: e: " + e);
            Log.d(TAG, "doInBackground: retrying");
        }          
        
        catch(Exception e){
            Log.d(TAG, "doInBackground: error 2 " + e.toString());
        }

想知道在 Android 上设置帖子消息的最佳方法是什么,即使手机处于飞行模式 5 小时,也要不断尝试连接直到连接成功。

编辑:按照下面@user3252344的回答,直接在AyncTask的catch block 中再次调用该函数是否有任何问题:

catch(UnknownHostException e){
            Log.d(TAG, "doInBackground: e: " + e);
            Log.d(TAG, "doInBackground: retrying");
            SendAlarm sendAlarm = new SendAlarm;
            sendAlarm.execute();
        }     

最佳答案

将连接超时设置为0意味着不会超时,但如果连接失败,它仍然不会处理。我猜您会收到 UnknownHostException ,因为它无法访问 DNS 服务器,因此无法解析 url。

我建议您设置一个合理的连接超时,如果发生超时异常,则捕获并重新运行。

final int READ_TIMEOUT = 500; // Timeout
final int RETRY_MS = 2000; //Retry every 2 seconds
final Handler handler = new Handler();

Runnable myUrlCall = () -> {
    try {
        //Make things
        urlConnect.setReadTimeout(READ_TIMEOUT);
        //Make the URL call, do response
    } catch (SocketTimeoutException e) {
        handler.postDelayed(myUrlCall, RETRY_MS);
    } catch (/* other unintended errors*/ e) {
        //Log the error or alert the user
    }
};

handler.post(myUrlCall);

可能更好的主意:在调用电话之前使用 Android 设置检查是否有互联网。如果没有互联网,请使用更长的延迟。 Something like this would be the code you're looking for .

关于Android 不断尝试 POST 直到成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66665059/

相关文章:

android - 在 Android 中使用 TLS 并禁用 SSL

Java - 使用 SSH 隧道连接到网页

android - 使用 ImageView 自定义可绘制对象

android - 使用阴影创建自定义 ListView

ruby-on-rails - rails 4 : Force method: :post

javascript - 使用 POST 在 JQuery 中传递数组并使用 Flask 读取它

java - Http URLConnection 等待内部请求

java - 如何向Volley的JsonArrayRequest传递参数

android - google 什么时候停止支持 c2dm 推送通知?

file - CakePHP HTTPsocket POST 文件上传