我正在制作一个简单的Android Wear应用程序来控制我的温度调节器,我使用Volley发送POST请求来控制它们。在Android Wear模拟器中一切正常(请求有效),但是,在我的Moto 360上加载应用程序时,volley请求被调用但总是超时。
为什么我的手表上volley请求失败了,而在模拟器上可以成功呢?其他应用程序的请求在我的手表上都能成功(例如内置的天气应用程序可以在约3秒钟内加载天气数据)。最奇怪的是:我曾经在我手表上让这个应用程序(成功地发起了volley请求),并且在从Android Studio安装到手表后的一天左右,它突然无法加载数据,原因不明。
我已经尝试过以下解决方法:
- 在我的manifest.xml中请求了Internet权限。 - 我将超时时间增加到30秒(见下面的代码),但没有改变任何东西。 - 我尝试通过蓝牙连接将我的计算机和模拟器连接到手机的连接上(以复制物理手表与手机之间的蓝牙连接),模拟器仍然可以成功地进行请求(虽然有两秒的延迟),排除了蓝牙速度太慢的可能性。 - 我确保API级别足够低,适用于运行Marshmallow的手表(我的手表和应用程序都是API级别23)。 - 我尝试在请求公司服务器上的温度调节器数据之前对Google进行了快速测试请求,虽然模拟器中的Google请求返回站点的HTML代码,但它在我的手表上超时了(在请求启动后30秒)。 - 我尝试将一些虚拟数据放入应该加载数据的回收视图中,虚拟数据确实出现了,排除了回收视图损坏的可能性。 - 我从手表中删除了应用程序并重新安装了它,并从我的手机中删除了陪同应用程序,重新安装了它,并再次将其删除,但都没有成功。 - 与Google支持团队的长时间交谈没有产生任何有意义的结果。
下面是我从主视图的适配器中提取的代码:
为什么我的手表上volley请求失败了,而在模拟器上可以成功呢?其他应用程序的请求在我的手表上都能成功(例如内置的天气应用程序可以在约3秒钟内加载天气数据)。最奇怪的是:我曾经在我手表上让这个应用程序(成功地发起了volley请求),并且在从Android Studio安装到手表后的一天左右,它突然无法加载数据,原因不明。
我已经尝试过以下解决方法:
- 在我的manifest.xml中请求了Internet权限。 - 我将超时时间增加到30秒(见下面的代码),但没有改变任何东西。 - 我尝试通过蓝牙连接将我的计算机和模拟器连接到手机的连接上(以复制物理手表与手机之间的蓝牙连接),模拟器仍然可以成功地进行请求(虽然有两秒的延迟),排除了蓝牙速度太慢的可能性。 - 我确保API级别足够低,适用于运行Marshmallow的手表(我的手表和应用程序都是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);
}
以下是从我的主活动中的onCreate()
方法调用的代码:
RequestQueue queue = Volley.newRequestQueue(this);
refreshThermostatsRecyclerView(queue);
如果您想查看在模拟器和手表上运行时创建的日志,可以在这里的Google Drive中找到。
编辑1:我的手表重新启动能够暂时解决问题并允许手表再次进行HTTP请求,但一旦手表断开蓝牙连接,连接WiFi,断开WiFi并重新连接蓝牙(因此每次我没有手机穿过公寓然后返回时都会出现问题)它就会再次出现问题。
编辑2:我将所有的volley请求都切换到Async线程中的HTTPURLConnection请求,但与volley相同的问题仍然存在。
tl;dr:我的应用程序的Volley请求在模拟器中工作,但在我的Android Wear手表上不再工作(尽管下载自Play Store的应用程序的类似请求可以工作),我该如何使我的应用程序的Volley请求在手表上再次工作?