AsyncHttpResponseHandler onsuccess方法在循环中不一致地调用

时间:2015-04-23 08:42:11

标签: android web-services rest asynchttpclient

我有一个代码调用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;
    }

2 个答案:

答案 0 :(得分:1)

这是因为异步通信意味着当你调用方法callWebservice()时,执行不会等待服务的回答,它会继续遍历表。

因此,当您尝试第二次调用该方法时,服务器可能仍然处于繁忙状态且无法处理该请求。

成功请求的不一致是因为网络性质不一致。

我建议使用某种形式的同步调用,以便在从服务器收到响应之前,客户端上的执行不会继续。

答案 1 :(得分:1)

AsyncHttpResponseHandlerandroid-async-httpcallback适用于Android的异步HTTP库。它会生成异步 HTTP请求,处理匿名回调中的响应。这意味着您可以在任何Thread发送请求,但在主线程callbacks中会返回,并且在提交请求后,callbacks不会立即得到响应。你知道,延迟,超时或其他不良案件都是通过互联网发生的。