【发布时间】:2021-10-30 08:55:09
【问题描述】:
我是 Android 应用程序开发的新手。我创建了一个简单的 hello world android 应用程序,我正在尝试调用在我的本地计算机上运行的 HelloWorldService 的 REST api 端点。该服务使用 IntelliJ 中的 Spring Boot 运行。服务代码如下:
@RestController
public class SimpleController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String sayHello() {
return "Hello world";
}
}
要从移动应用程序调用此 api,我使用的是 Retrofit 库。代码如下:
依赖关系
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
SimpleService.java
public interface SimpleService {
@GET("/hello")
Call<String> sayHello();
}
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
TextView textView = findViewById(R.id.textView);
button.setOnClickListener(view -> {
OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://x.x.x.x:8080")
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
final SimpleService simpleService = retrofit.create(SimpleService.class);
final Call<String> stringCall = simpleService.sayHello();
stringCall.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
textView.setText(response.body());
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
t.printStackTrace();
}
});
});
}
我尝试了什么?
- 谷歌搜索后,我了解到我不能使用
localhost作为访问网络服务的IP地址,我必须使用实际的网络IP。此外,笔记本电脑和手机需要在同一个网络上。因此,我更新了我的基本 url 以使用 inet 地址x.x.x.x:port_number。 - 我已验证两台设备都连接到同一个 wi-fi。
- 我已授予我的 Android 应用程序的互联网权限。
<uses-permission android:name="android.permission.INTERNET" /> - 在笔记本电脑中尝试过邮递员和网络浏览器。我得到了正确的答复。
- 尝试使用移动浏览器调用服务。我无法访问它。
- 使用了特殊地址
10.0.2.2的模拟器,我可以访问它。
但是,我无法连接到端点并收到以下错误:
W/System.err: java.net.SocketTimeoutException: failed to connect to /192.168.0.11 (port 8080) from /192.168.0.26 (port 56860) after 120000ms
W/System.err: at libcore.io.IoBridge.connectErrno(IoBridge.java:191)
at libcore.io.IoBridge.connect(IoBridge.java:135)
W/System.err: at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
W/System.err: at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:621)
at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:71)
at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:263)
W/System.err: at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:183)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:108)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:88)
at okhttp3.internal.connection.Transmitter.newExchange(Transmitter.java:169)
W/System.err: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
W/System.err: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:229)
W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:172)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
感谢任何指针。
【问题讨论】:
-
您应该能够通过使用邮递员甚至您的浏览器来测试它是否与服务有关,以查看 url 是否通过它们给出错误。可能是您的计算机阻止了连接
-
是的,我对此进行了测试,邮递员和网络浏览器都可以正常工作。我可以使用它们访问服务。
-
在您的 Android 设备上使用浏览器。
-
不要将您的服务器绑定到本地 ip 或 127.0.0.1。根本不要绑定。
标签: android spring-boot rest retrofit2