java - 无法在android中发出http请求
问题描述
我正在尝试制作一个简单的 android 应用程序,该应用程序向 google 发出请求,我的应用程序应该与 google 建立连接然后停止的预期行为,我得到了这个错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 4431
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
at android.view.View.performClick(View.java:7339)
at android.widget.TextView.performClick(TextView.java:14275)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7305)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27787)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7078)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:7339)
at android.widget.TextView.performClick(TextView.java:14275)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7305)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27787)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7078)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
at java.net.InetAddress.getAllByName(InetAddress.java:1154)
at com.android.okhttp.Dns$1.lookup(Dns.java:39)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:196)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:144)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:89)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:190)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:142)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:104)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:392)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:325)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:488)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
at com.example.myapplication.HttpRequest.request(HttpRequest.java:25)
at com.example.myapplication.MainActivity.onClick(MainActivity.java:64)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:7339)
at android.widget.TextView.performClick(TextView.java:14275)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7305)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27787)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7078)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
我正在使用 API 30 开发 android studio 4.1.2,我正在使用 android 9 Pie 在我的手机上运行该应用程序。我的应用程序有一个发出请求的按钮,正在执行的按钮就在这里:
public void onClick(View view) {
try {
URL url = new URL("http://www.google.com/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
//do something
conn.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
我尝试了在互联网上找到的解决方案,但没有任何效果,我尝试编辑我的 AndroidManifest.xml 并以以下方式结束:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity android:name=".MainActivity2"></activity>
<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>
我创建了一个文件 network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">google.com</domain>
</domain-config>
</network-security-config>
我是移动开发的新手,我不了解 xml 文件中的所有内容,所以可能有明显的错误,但我没有看到。
谢谢您的帮助。
解决方案
根据您的错误日志,您的问题是您试图在主线程上连接到互联网。Android 不允许您在主线程上设置 Internet 连接,因为这会在建立连接时冻结其他所有内容。您需要在不同的线程上连接。
编辑:鉴于AsyncTask
已贬值,推荐的替代方案似乎是使用其中包含的接口java.util.concurrent
来制作线程和/或线程池或 Kotlin 的协程库。请务必检查文档并创建一个在后台建立连接的线程。
推荐阅读
- javascript - 如何将断线从 App 脚本添加到 Google 表格
- java - Android 数据绑定真的是一个全有或全无的命题吗?
- python - 根据两个数据框之间的比较匹配创建列
- python - "errorMessage": "模块 'lambda_function' 上缺少处理程序 'lambda_handler'",
- linux - posix aio和freebsd aio有什么区别?
- swift - 如何转换范围
到 Swift 中的字符串 - c# - Discord.net 更好的帮助命令
- scala - FS2 队列生产者和消费者
- wifi - 如何丢弃在 NS-3 网状节点中捕获的特定数据包?
- django - 有人可以解释何时/如何使用 Queryset 修改与 Django Rest Framework 的权限吗?