Volley 本地请求仅在连接到 USB 调试时有效
Volley local request only works when attached to USB debugging
我正在构建一个充当测量设备和网络应用程序之间代理的应用程序。这是必要的,因为测量设备不提供 CORS/HTTPS 实现,不能直接从 Web 应用程序调用。
这通过使用我的 phone 创建一个热点并将测量设备连接到它来实现。然后我们 运行 一个托管 RouterNanoHTTP 服务器实例的后台服务。这个实例基本上只是将调用转发给测量设备。
我的应用程序在连接到计算机的 USB 时运行良好。然而,第二次我拔下 USB 线所有请求到测量设备 return 一个 Volley 超时错误。我尝试了多种方法,包括设置 binded network adapter manually。仍然可以从我的 phone 的浏览器访问测量设备。因此,我认为它更像是某种配置错误而不是代码错误。
我的 AndroidManifest 中有互联网和 ACCESS_NETWORK_STATE。
编辑:看来这可能与我对 HttpServer 的实现有关。我在我的视图中添加了一个按钮来调用 API,并且在与 USB 断开连接时仍然有效。但是,通过 HttpServer 发出的任何请求都不再有效。
相关代码:
override fun getUrl(url: String, callback: (result: String?) -> Unit) {
val req = StringRequest(
Request.Method.GET, url,
Response.Listener<String> { res -> callback(res) },
Response.ErrorListener { err ->
Log.d("MD-ERROR", err.toString());
callback(null)
}
)
req.retryPolicy = DefaultRetryPolicy(
5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
)
this.requestQueue.add(req)
}
HTTP 服务器:
class HttpServerWrapper(private val port: Int, private val xrfConnector: IXrfConnector) : AsyncHttpServer() {
/**
* Starts the server
*/
fun startServer() {
this.addMappings()
this.listen(this.port)
}
fun addMappings() {
this.get("/") { _, response: AsyncHttpServerResponse ->
response.headers.add("Access-Control-Allow-Origin", "*")
this.xrfConnector.getMeasurements {
val gson = Gson()
val json = gson.toJson(it?.measurements)
response.send(json)
response.end()
}
}
}
VolleyDebug 的输出(第一个请求是连接 USB,第二个没有):
2021-01-19 10:21:03.037 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (785 ms) [ ] http://192.168.43.9:8080/xapi/measurements?startDate=2021-01-12 0x676a9949 NORMAL 2
2021-01-19 10:21:03.038 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+0 ) [1621] add-to-queue
2021-01-19 10:21:03.040 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+1 ) [1613] cache-queue-take
2021-01-19 10:21:03.043 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+4 ) [1613] cache-hit-expired
2021-01-19 10:21:03.045 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+2 ) [1616] network-queue-take
2021-01-19 10:21:03.049 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+583 ) [1616] network-http-complete
2021-01-19 10:21:03.062 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+16 ) [1616] network-parse-complete
2021-01-19 10:21:03.065 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+4 ) [1616] network-cache-written
2021-01-19 10:21:03.068 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+0 ) [1616] post-response
2021-01-19 10:21:03.069 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+175 ) [ 2] done
2021-01-19 10:21:11.193 26316-26432/my.app.bridge I/System.out: http://192.168.43.9:8080/xapi/measurements?startDate=2021-01-12
2021-01-19 10:21:11.201 26316-26422/my.app.bridge D/Volley: [1613] WaitingRequestManager.maybeAddToWaitingRequests: new request, sending to network http://192.168.43.9:8080/xapi/measurements?startDate=2021-01-12
2021-01-19 10:21:26.390 26316-26316/my.app.bridge D/XRF-ERROR: com.android.volley.TimeoutError
2021-01-19 10:21:26.425 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (15229 ms) [ ] http://192.168.43.9:8080/xapi/measurements?startDate=2021-01-12 0x676a9949 NORMAL 3
2021-01-19 10:21:26.428 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+0 ) [1621] add-to-queue
2021-01-19 10:21:26.434 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+1 ) [1613] cache-queue-take
2021-01-19 10:21:26.439 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+5 ) [1613] cache-hit-expired
2021-01-19 10:21:26.441 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+4 ) [1615] network-queue-take
2021-01-19 10:21:26.443 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+5104) [1615] socket-retry [timeout=5000]
2021-01-19 10:21:26.448 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+10080) [1615] socket-timeout-giveup [timeout=10000]
2021-01-19 10:21:26.450 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+0 ) [1615] post-error
2021-01-19 10:21:26.455 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+35 ) [ 2] done
问题出在您向其发送请求的 URL 上。
如果您的设备通过 USB 连接到您的系统,请尝试
http://10.0.2.2/myserverfile.php
否则,如果您的服务器在线托管,请使用 http://www.myserverlocation.blah/myserverfile.php
所以,问题似乎出在为应用程序启用了电池优化。禁用此功能后,请求顺利通过。
唯一奇怪的是您没有收到任何错误或记录您的请求被阻止。我是在使用另一个 HTTP 库后才通过这一行发现的:
2021-01-25 12:02:53.881 4942-1564/system_process D/ConnectivityService: Returning BLOCKED NetworkInfo to uid=xxx
调试了一周:D.
我正在构建一个充当测量设备和网络应用程序之间代理的应用程序。这是必要的,因为测量设备不提供 CORS/HTTPS 实现,不能直接从 Web 应用程序调用。
这通过使用我的 phone 创建一个热点并将测量设备连接到它来实现。然后我们 运行 一个托管 RouterNanoHTTP 服务器实例的后台服务。这个实例基本上只是将调用转发给测量设备。
我的应用程序在连接到计算机的 USB 时运行良好。然而,第二次我拔下 USB 线所有请求到测量设备 return 一个 Volley 超时错误。我尝试了多种方法,包括设置 binded network adapter manually。仍然可以从我的 phone 的浏览器访问测量设备。因此,我认为它更像是某种配置错误而不是代码错误。
我的 AndroidManifest 中有互联网和 ACCESS_NETWORK_STATE。
编辑:看来这可能与我对 HttpServer 的实现有关。我在我的视图中添加了一个按钮来调用 API,并且在与 USB 断开连接时仍然有效。但是,通过 HttpServer 发出的任何请求都不再有效。
相关代码:
override fun getUrl(url: String, callback: (result: String?) -> Unit) {
val req = StringRequest(
Request.Method.GET, url,
Response.Listener<String> { res -> callback(res) },
Response.ErrorListener { err ->
Log.d("MD-ERROR", err.toString());
callback(null)
}
)
req.retryPolicy = DefaultRetryPolicy(
5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
)
this.requestQueue.add(req)
}
HTTP 服务器:
class HttpServerWrapper(private val port: Int, private val xrfConnector: IXrfConnector) : AsyncHttpServer() {
/**
* Starts the server
*/
fun startServer() {
this.addMappings()
this.listen(this.port)
}
fun addMappings() {
this.get("/") { _, response: AsyncHttpServerResponse ->
response.headers.add("Access-Control-Allow-Origin", "*")
this.xrfConnector.getMeasurements {
val gson = Gson()
val json = gson.toJson(it?.measurements)
response.send(json)
response.end()
}
}
}
VolleyDebug 的输出(第一个请求是连接 USB,第二个没有):
2021-01-19 10:21:03.037 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (785 ms) [ ] http://192.168.43.9:8080/xapi/measurements?startDate=2021-01-12 0x676a9949 NORMAL 2
2021-01-19 10:21:03.038 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+0 ) [1621] add-to-queue
2021-01-19 10:21:03.040 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+1 ) [1613] cache-queue-take
2021-01-19 10:21:03.043 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+4 ) [1613] cache-hit-expired
2021-01-19 10:21:03.045 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+2 ) [1616] network-queue-take
2021-01-19 10:21:03.049 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+583 ) [1616] network-http-complete
2021-01-19 10:21:03.062 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+16 ) [1616] network-parse-complete
2021-01-19 10:21:03.065 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+4 ) [1616] network-cache-written
2021-01-19 10:21:03.068 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+0 ) [1616] post-response
2021-01-19 10:21:03.069 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+175 ) [ 2] done
2021-01-19 10:21:11.193 26316-26432/my.app.bridge I/System.out: http://192.168.43.9:8080/xapi/measurements?startDate=2021-01-12
2021-01-19 10:21:11.201 26316-26422/my.app.bridge D/Volley: [1613] WaitingRequestManager.maybeAddToWaitingRequests: new request, sending to network http://192.168.43.9:8080/xapi/measurements?startDate=2021-01-12
2021-01-19 10:21:26.390 26316-26316/my.app.bridge D/XRF-ERROR: com.android.volley.TimeoutError
2021-01-19 10:21:26.425 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (15229 ms) [ ] http://192.168.43.9:8080/xapi/measurements?startDate=2021-01-12 0x676a9949 NORMAL 3
2021-01-19 10:21:26.428 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+0 ) [1621] add-to-queue
2021-01-19 10:21:26.434 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+1 ) [1613] cache-queue-take
2021-01-19 10:21:26.439 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+5 ) [1613] cache-hit-expired
2021-01-19 10:21:26.441 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+4 ) [1615] network-queue-take
2021-01-19 10:21:26.443 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+5104) [1615] socket-retry [timeout=5000]
2021-01-19 10:21:26.448 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+10080) [1615] socket-timeout-giveup [timeout=10000]
2021-01-19 10:21:26.450 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+0 ) [1615] post-error
2021-01-19 10:21:26.455 26316-26316/my.app.bridge D/Volley: [2] MarkerLog.finish: (+35 ) [ 2] done
问题出在您向其发送请求的 URL 上。
如果您的设备通过 USB 连接到您的系统,请尝试
http://10.0.2.2/myserverfile.php
否则,如果您的服务器在线托管,请使用 http://www.myserverlocation.blah/myserverfile.php
所以,问题似乎出在为应用程序启用了电池优化。禁用此功能后,请求顺利通过。
唯一奇怪的是您没有收到任何错误或记录您的请求被阻止。我是在使用另一个 HTTP 库后才通过这一行发现的:
2021-01-25 12:02:53.881 4942-1564/system_process D/ConnectivityService: Returning BLOCKED NetworkInfo to uid=xxx
调试了一周:D.