
Android 请求接口
10.0.2.2
在Android Emulator中,localhost 指的是模拟器本身的回环地址,而不是开发机器的回环地址。因此,如果你在模拟器中使用 localhost,它会尝试连接到模拟器自身的服务,而不是开发机器上的服务。这就是为什么你需要使用开发机器的局域网IP地址(例如 10.213.121.155)来访问本地运行的Spring Boot应用。
为什么不能直接使用 localhost?
模拟器回环地址:
localhost 或 127.0.0.1 在模拟器中指向的是模拟器本身。
如果你的Spring Boot应用运行在开发机器上,模拟器无法通过 localhost 访问到开发机器上的服务。
开发机器局域网IP:
使用开发机器的局域网IP地址(例如 10.213.121.155)可以确保模拟器通过网络连接到开发机器上的服务。
使用 10.0.2.2 的情况
如果你使用的是Android Emulator,还有一个特殊的IP地址 10.0.2.2,它可以用来访问开发机器上的服务。这个地址是Android Emulator提供的一个别名,用于指向开发机器的回环地址(127.0.0.1)。
使用 10.0.2.2 的示例
如果你选择使用 10.0.2.2,你可以将 BASE_URL 修改为:
package com.android.webttest.Config;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {
private static final String BASE_URL = "http://10.0.2.2:8080/api/"; // 使用10.0.2.2
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
确保网络权限
确保在你的 AndroidManifest.xml 文件中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
package com.android.webttest.activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.android.webttest.Api.Service.Checkcode;
import com.android.webttest.Config.ApiClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建Checkcode接口实例
Checkcode checkcodeService = ApiClient.getClient().create(Checkcode.class);
// 调用getCheckcode方法
Call<String> call = checkcodeService.getCheckcode();
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
String checkcode = response.body();
Log.d("MainActivity", "Checkcode received: " + checkcode);
// 例如,将验证码显示在TextView中
TextView checkcodeTextView = findViewById(R.id.checkcodeTextView);
checkcodeTextView.setText(checkcode);
} else {
Log.d("MainActivity", "Failed to get checkcode: " + response.code());
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("MainActivity", "Failed to get checkcode: " + t.getMessage());
}
});
}
}
Failed to get checkcode: CLEARTEXT communication to 10.0.2.2 not permitted by network security policy为什么
错误信息 Failed to get checkcode: CLEARTEXT communication to 10.0.2.2 not permitted by network security policy 表明应用尝试通过 HTTP(明文通信)访问网络资源,但被 Android 的网络安全策略阻止。
原因
Android 的网络安全策略
从 Android 9.0(API 级别 28)开始,默认情况下,应用不允许使用明文(HTTP)进行网络通信。所有网络请求必须使用 HTTPS。
如果需要使用 HTTP,必须显式配置应用的网络安全策略。
IP 地址 10.0.2.2
10.0.2.2 是 Android 模拟器中的特殊 IP 地址,指向主机机器(开发者的电脑)。通常用于调试或本地 API 测试。
由于它是 HTTP 而非 HTTPS,因此被默认的安全策略阻止。
解决方案
方法 1:在 AndroidManifest.xml 中允许明文通信
如果测试环境仅限于本地调试,可以通过修改 AndroidManifest.xml 文件来允许明文通信。
在 <application> 标签中添加以下属性:
android:usesCleartextTraffic="true"
<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/Theme.WebTTest"
android:usesCleartextTraffic="true"> <!-- 允许明文通信 -->
</application>