【发布时间】:2017-04-08 19:33:38
【问题描述】:
我正在制作一个简单的 Android Wear 应用来控制我的恒温器,并且我正在使用 Volley 发送 POST 请求来控制它们。在 Android Wear 模拟器中一切正常(请求有效),但是,当应用程序在我的 Moto 360 上加载时,volley 请求被调用但总是超时。
为什么我的 volley 请求在我的手表上失败但在模拟器上工作?其他应用在我的手表上请求成功(例如,内置天气应用可以在大约 3 秒内加载天气数据)。而且,最奇怪的部分:我的手表上有应用程序工作(成功发出截击请求),并且在我从 Android Studio 将它安装到手表后大约一天,它突然停止加载数据没有明显的原因。
到目前为止我所做的尝试:
- 我已在我的
manifest.xml中请求互联网许可。 - 我已将超时时间增加到 30 秒(请参阅下面的代码),这并没有改变任何内容。
- 我已尝试通过蓝牙将我的计算机和模拟器连接到我的手机连接(复制我的物理手表与我的手机的蓝牙连接),模拟器仍然成功发出请求(尽管有两秒的延迟) ,排除蓝牙太慢的可能。
- 我确保我的 Marshmallow 手表的 API 级别足够低(我的手表和应用程序都是 API 级别 23)。
- 我尝试在使用我的恒温器数据向公司服务器发出请求之前向 Google 发出快速测试请求,当 Google 请求在模拟器中返回站点的 HTML 代码时,它在我的手表上超时(请求后 30 秒已启动)。
- 我尝试将一些虚拟数据放入应加载的回收站视图中,并且虚拟数据确实出现了,排除了回收站视图已损坏。
- 我把手表里的应用删了重装,手机删了伴侣,重装了,又删了,都没用。
- 与 Google 支持人员的长时间交谈没有产生任何有意义的结果。
这是我的代码(来自我的主视图的适配器):
public void refreshThermostatsRecyclerView(RequestQueue queue) {
String url = "https://mobile.skyport.io:9090/login"; // login call to the thermostats server Skyport
Log.w("myApp", "Starting /login call to Skyport"); // this gets called on simulator and watch
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the response string.
Log.w("myApp", "Response is: " + response); // this gets called on the simulator but not the watch
try {
// there's some code to parse the data.
} catch (JSONException e) {
Log.w("myApp", "catching an error parsing the json."); // never gets called.
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.w("myApp", "Skyport request didn't work! " + error); // this always gets called on the watch, with the error being a timeout error (com.Android.Volley.timeouterror) but never gets called in the simulator
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> m = new HashMap<>();
m.put("Referer", "app:/VenstarCloud.swf");
// here I put some more headers
return m;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> m = new HashMap<>();
m.put("version", "3.0.5");
m.put("email", userEmail);
m.put("password", userToken);
return m;
}
};
// Add the request to the RequestQueue.
int socketTimeout1 = 30000; // times out 30 seconds after the request starts on the watch
RetryPolicy policy1 = new DefaultRetryPolicy(socketTimeout1, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(policy1);
queue.add(stringRequest);
}
使用以下代码从我的 Main Activity 中的 onCreate() 方法调用:
RequestQueue queue = Volley.newRequestQueue(this);
refreshThermostatsRecyclerView(queue);
如果您想查看通过在模拟器和手表上运行此创建的日志,它们是on Google Drive here。
编辑 1: 重新启动我的手表可以暂时解决此问题并允许手表再次发出 HTTP 请求,但一旦手表与蓝牙断开连接、连接到 WiFi、与 WiFi 断开连接,它就会再次中断,然后重新连接到蓝牙(所以每次我不带手机穿过公寓然后返回时它都会中断)。
编辑 2:我在异步线程中将 volley 请求全部切换到 HTTPURLConnection Requests,并且出现与 volley 相同的问题。
tl;dr:我的应用程序的 Volley 请求在模拟器中有效,但在我的 Android Wear 手表上不再有效(尽管 Play 商店下载的应用程序的类似请求有效),我怎样才能获得 volley请求在手表上再次使用我的应用程序?
【问题讨论】:
-
@MelissaRojas 在下面的回答暂时但不是永久地解决了这个问题,正如您将在我的问题的编辑 1 中看到的那样。所以我我仍在寻找答案。
-
你试过禁用缓存吗?
-
@AnixPasBesoin 应用程序或 httpurlconnection 的缓存?
-
Volley 的缓存。
-
@AnixPasBesoin 现在使用 HTTPURLConnection,所以设置
myURLConnection.setUseCaches(false);,这没有帮助。还尝试在应用以this 关闭时自动清除应用缓存,但无济于事。还有什么我可以尝试的吗?
标签: java android android-volley wear-os