【问题标题】:Android app hangs on HttpUrlConnection requestAndroid 应用程序挂起 HttpUrlConnection 请求
【发布时间】:2020-08-10 19:04:21
【问题描述】:

我创建了一个小演示程序

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        (new Requester()).execute();
    }

    static class Requester extends AsyncTask<Void, Void, Void>{
        @Override
        protected Void doInBackground(Void... voids) {
            URL loginURL;
            HttpURLConnection urlConnection;
            try {
                loginURL = new URL("https://google.com");
                urlConnection = (HttpURLConnection) loginURL.openConnection();

                int responseCode = urlConnection.getResponseCode();
                Log.d("response", "response is" + responseCode);
            }
            catch (MalformedURLException e){
                e.printStackTrace();
            }
            catch (IOException e){
                e.printStackTrace();
            }
            return null;
        }
    }
}

我在int responseCode = urlConnection.getResponseCode(); 处设置了一个断点,然后单步执行。它永远不会到达下一行让我阅读响应代码。没有错误;它只是永远挂起。

我觉得这是我能想到的最基本的 urlconnection 代码。也许我错过了一些重要的东西。

编辑:我确实在我的清单中添加了互联网权限。这是我的整个清单,以防万一:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testingcorruptbitmap">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

更新: 我已经编辑了我的代码以包括从请求中读取。

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        (new Requester()).execute();
    }

    static class Requester extends AsyncTask<Void, Void, Void>{
        @Override
        protected Void doInBackground(Void... voids) {
            URL loginURL;
            HttpURLConnection urlConnection;
            try {
                loginURL = new URL("https://google.com");
                urlConnection = (HttpURLConnection) loginURL.openConnection();
                InputStream in = new BufferedInputStream(urlConnection.getInputStream());
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String line = reader.readLine();
                Log.d("urlconnection", "line is " + line);
                int responseCode = urlConnection.getResponseCode();
                Log.d("urlconnection", "response is " + responseCode);
            }
            catch (MalformedURLException e){
                e.printStackTrace();
            }
            catch (IOException e){
                e.printStackTrace();
            }
            catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }
    }
}

当我在代码和演练的开头设置断点时,它冻结在InputStream in = new BufferedInputStream(urlConnection.getInputStream()); 所以这并不能解决问题。

解决方案更新: 我正在使用的 android 模拟设备出了点问题。我重新启动它,现在问题已解决。如果您知道发生这种情况的原因,请让我和互联网上的其他人知道,这样我们就可以避免它!

【问题讨论】:

  • 检查清单中是否包含互联网权限。
  • 我已经添加了。事实上,我的应用一开始就崩溃了,因为我没有添加它,所以我必须先解决这个问题。
  • 请添加更多错误日志
  • @McSlinPlay 不再有错误日志。我添加了互联网权限,所以没有错误。它只是冻结
  • 即使您删除断点并实时执行代码?

标签: android httpurlconnection


【解决方案1】:

您没有发出实际请求,因此也没有响应,这就是您的代码正在等待响应的原因。

请看这里:Http Get using Android HttpURLConnection

【讨论】:

  • 请查看我的更新。我尝试使用 getInputStream 但它仍然冻结
【解决方案2】:

您是否在 AndroidManifest 中添加了 INTERNET 权限?如果不这样做。 如果您确实查看了 android-dev 的 this 文档。它展示了如何使用 volley 库发出简单的请求。

希望对你有帮助

编辑: 我个人从未使用过 URLConnection,但根据 android 文档,您必须这样做:

   URL url = new URL("http://www.android.com/");
   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
   try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     readStream(in);
   } finally {
     urlConnection.disconnect();
   }

来源:https://developer.android.com/reference/java/net/HttpURLConnection

在您的示例中,您刚刚创建了一个 HttpURLConnection 但从未执行过它,这就是为什么您无法得到它的原因。

虽然它绝对可以使用这种方法,但我强烈建议您看看 Volley,因为它更简单且更易于使用。它还可以帮助您处理 JSONRequests。此外,默认情况下它是异步的,这意味着您不再需要使用已弃用的 AsyncTask。

编辑 2: 当您尝试在示例中尝试通过 https 连接到安全网站时,您需要转换为 HttpsURLConnection。

【讨论】:

  • 查看我对互联网权限问题的原始问题的更新。至于 Volley——我不打算完全重写我的应用程序以使用不同的工具,抱歉。你知道如何避免我的 UrlConnection 问题吗?我认为 UrlConnection 应该具有基本功能,即使它不具备 volley 的功能
  • 查看我的最新更新。从请求中读取没有帮助
  • 我改为使用 HttpsUrlConnection ,但它仍然冻结。如果你愿意,我可以发布更新的代码
【解决方案3】:

我也有同样的问题,getResponseCode 方法的调用冻结。如果我设置了超时,则会抛出超时过期异常。 但是当我将手机置于省电模式时会发生上述所有情况,如果我将其移除,则对 getResponseCode 方法的调用会完美运行。

如果使用 Volley api,也会发生超时。

但这仅发生在后台进程中,例如由于系统施加的限制而更新小部件时。

解决方案是将您的应用添加到节能排除列表中。虽然这可以通过 PowerManager api 完成,但最好由您的应用程序的用户来执行此操作,如本答案 https://stackoverflow.com/a/53115804/1735246 中所述。

【讨论】:

    猜你喜欢
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多