问题描述
我已将此添加到清单
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
我已经添加了要拉入的 gradle 组件,否则它甚至无法编译,但这段代码绝对没有任何作用。当我将它复制到一个空的应用程序中时,该应用程序崩溃了。
我已尝试将其放入“基本操作”示例中,该示例至少不会崩溃,但代码不会发出 http 请求。
package com.example.hellokitty;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
public static void main(String[] args) throws IOException {
MainActivity example = new MainActivity();
String response = example.run("http://10.10.0.11/kek");
System.out.println(response);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view,"Replace with your own action",Snackbar.LENGTH_LONG)
.setAction("Action",null).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main,menu);
return true;
}
@Override
public boolean onoptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button,so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onoptionsItemSelected(item);
}
}
解决方法
我已经试过你的代码了。 它崩溃是因为您在主线程上运行网络操作。你得到 NetworkOnMainThreadException 运行时异常。
为了避免这种情况,您需要更换
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
与
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call,@NotNull IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(@NotNull Call call,@NotNull Response response) throws IOException {
String url = response.body().string();
//your code here
}
});
整个代码将是:
public class MainActivity extends AppCompatActivity {
private OkHttpClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
client = new OkHttpClient();
run("http://10.10.0.11/kek");
}
private void run(String url) {
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call,@NotNull IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(@NotNull Call call,@NotNull Response response){
String url = response.body().toString();
//your code here
}
});
}
}
从 Android 9(API 级别 28)开始,默认情况下禁用明文支持。
因此,当您拨打 http://10.10.0.11/kek 时,您将收到 java.io.IOException: * 不允许的明文 HTTP 流量
这就是您需要在安全配置中启用明文流量的原因。
在您的 AndroidManifest.xml 中:
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
</manifest>
创建文件 res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>