我有一个代码调用PHP Web服务从mysql中获取json中的数据。 这个json响应然后用于将android设备同步到sqlite。 我为每个表创建了1个php。 当我只为1个表执行服务时,一切正常。但是,我创建了一个表名称及其要调用的URL的映射,当我在循环中调用此服务时,该服务仅在地图中的10个以上的条目中被调用1或2个URL,并且也是不一致的方式,永远不会完全适用于所有条目。
请指导什么错误。
public void syncAllFromRemote() {
Toast.makeText(getApplicationContext(), "Synchronizing app...Please Wait...", Toast.LENGTH_SHORT).show();
Map<String, String> urlMap = new LinkedHashMap<String, String>();
urlMap.put("oc_address", "/get_oc_address.php");
urlMap.put("oc_category", "/get_oc_category.php");
urlMap.put("oc_product", "/get_oc_product.php");
urlMap.put("oc_category_description", "/get_oc_category_description.php");
urlMap.put("oc_customer_group", "/get_oc_customer_group.php");
urlMap.put("oc_customer", "/get_oc_customer.php");
urlMap.put("oc_product_description", "/get_oc_product_description.php");
urlMap.put("oc_customer_group_description", "/get_oc_customer_group_description.php");
urlMap.put("oc_product_mapping", "/get_oc_product_mapping.php");
urlMap.put("oc_product_special", "/get_oc_product_special.php");
urlMap.put("oc_product_to_category", "/get_oc_product_to_category.php");
urlMap.put("oc_product_to_customer_group", "/get_oc_product_to_customer_group.php");
urlMap.put("oc_order", "/get_oc_order.php");
for (Map.Entry<String, String> entry : urlMap.entrySet()) {
final String tableName = entry.getKey();
final String url = entry.getValue();
callWebservice(tableName, url);
}
if (syncStatus) {
Toast.makeText(getApplicationContext(), "Synchronization completed successfully", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(getApplicationContext(), "Synchronization faced some problems", Toast.LENGTH_SHORT).show();
}
updateSyncDetails(syncStatus);
Toast.makeText(getApplicationContext(), "Updated sync details", Toast.LENGTH_SHORT).show();
reloadActivity();
}
private void callWebservice(final String tableName, String url) {
SyncHelper.get(url, null, new AsyncHttpResponseHandler() {
@Override
public void onStart() {
super.onStart();
Log.i("onStart", "OKOKOK");
}
@Override
public void onSuccess(String response) {
super.onSuccess(response);
System.out.println("Calling copy method " + tableName);
copyToSQLite(tableName, response);
Toast.makeText(getApplicationContext(), tableName + " : Success", Toast.LENGTH_LONG).show();
}
@Override
public void onFinish() {
super.onFinish();
Log.i("onFinish", "OKOKOK");
}
@Override
public void onFailure(int statusCode, Throwable error, String content) {
super.onFailure(error, content);
System.out.println("On faliure" + tableName);
syncStatus = false;
if (statusCode == 404) {
Toast.makeText(getApplicationContext(), tableName + " : Requested resource not found",
Toast.LENGTH_LONG).show();
} else if (statusCode == 500) {
Toast.makeText(getApplicationContext(), tableName + " : Something went wrong at server end",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(
getApplicationContext(),
tableName
+ " : Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]. Status Code : "
+ statusCode, Toast.LENGTH_LONG).show();
}
}
});
}
public void copyToSQLite(String tableName, String response) {
System.out.println("In copy method for : " + tableName);
System.out.println(response);
ArrayList<HashMap<String, String>> syncList;
syncList = new ArrayList<HashMap<String, String>>();
LinkedHashMap<String, LinkedHashMap<String, String>> tablesMap = DBHelper.defineTablesFromMySql();
Gson gson = new GsonBuilder().create();
try {
JSONArray arr = new JSONArray(response);
if (arr.length() != 0) {
System.out.println("JSON Array for " + tableName + " : " + arr);
LinkedHashMap<String, String> tableDetails = tablesMap.get(tableName);
for (int i = 0; i < arr.length(); i++) {
JSONObject obj = (JSONObject) arr.get(i);
queryValues = new HashMap<String, String>();
for (Map.Entry<String, String> entry : tableDetails.entrySet()) {
String key = entry.getKey();
queryValues.put(entry.getKey(), obj.get(entry.getKey()).toString());
}
controller.insertTableFromMySql(tableName, queryValues);
HashMap<String, String> map = new HashMap<String, String>();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
SyncHelper class
private static final String BASE_URL = "http://10.0.2.2/mysqltosqlitesync";
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.post(getAbsoluteUrl(url), params, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
答案 0 :(得分:1)
这是因为异步通信意味着当你调用方法callWebservice()
时,执行不会等待服务的回答,它会继续遍历表。
因此,当您尝试第二次调用该方法时,服务器可能仍然处于繁忙状态且无法处理该请求。
成功请求的不一致是因为网络性质不一致。
我建议使用某种形式的同步调用,以便在从服务器收到响应之前,客户端上的执行不会继续。
答案 1 :(得分:1)
AsyncHttpResponseHandler
是android-async-http
的callback
,适用于Android的异步HTTP库。它会生成异步 HTTP请求,处理匿名回调中的响应。这意味着您可以在任何Thread
发送请求,但在主线程callbacks
中会返回,并且在提交请求后,callbacks
不会立即得到响应。你知道,延迟,超时或其他不良案件都是通过互联网发生的。