使用 Volley 请求 JSON

Requesting JSON with Volley

我正在尝试做一个显示存储在 SQLite database 中的文章的应用程序。 我在我的服务器上使用 php 函数来获取包含我的数据库的 JSON 文件。在我的 Android 应用程序中,我想获取 JSON 并将其放入 JSONObject,我执行了以下操作:

private void initDataset() {
    mDataset = new ArrayList<>();
    Log.d("InitDataset", String.valueOf(mDataset.size()));
    getArticles();
    Log.d("InitDataset", String.valueOf(mDataset.size()));


}

public void getResponse(int method, String url, JSONObject jsonValue, final VolleyCallback callback) {
    StringRequest strreq = new StringRequest(method, url, new Response.Listener < String > () {

        @Override
        public void onResponse(String Response) {
            callback.onSuccessResponse(Response);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError e) {
            e.printStackTrace();
            Toast.makeText(getContext(), e + "error", Toast.LENGTH_LONG).show();
        }
    });

    AppController.getInstance().addToRequestQueue(strreq);
}

public void getArticles() {
    getResponse(Request.Method.GET, AppConfig.URL_ARTICLE, null,
            new VolleyCallback() {
                @Override
                public void onSuccessResponse(String result) {
                    for (int i = 1; i < 3; i++) {
                        try {
                            Article article = new Article();

                            JSONObject response = new JSONObject(result);

                            // Now store the articles in SQLite
                            JSONObject articleObj = response.getJSONObject("article" + i);
                            article.setArticle_id(i);
                            article.setPicture_url(articleObj.getString("picture_url"));
                            article.setName(articleObj.getString("name"));
                            article.setDescription(articleObj.getString("description"));
                            article.setQuantity(Float.parseFloat(articleObj.getString("quantity")));
                            article.setPrice(Float.parseFloat(articleObj.getString("price")));
                            mDataset.add(article);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }
                }
            });
}

public interface VolleyCallback {
    void onSuccessResponse(String result);
}

但是在日志中,mDataset 的大小始终为 0。或者如果我在 onResponse() 中记录例如文章的名称,我可以看到每个名称都在数据库中。 (因此我认为连接和 php 功能没问题)

有什么想法吗?

这是 php 文件:

<?php
require_once 'include/DB_Functions.php';
$db = new DB_Functions();

// JSON response array
$response = array("error" => FALSE);

$article = $db->getAllArticles();

if ($article != false) {
    // use is found
    $response["error"] = FALSE;

    while($row = $article->fetch_assoc()) {
        $response["article".$row["article_id"]]["article_id"] = $row["article_id"];
        $response["article".$row["article_id"]]["picture_url"] = $row["picture_url"];
        $response["article".$row["article_id"]]["name"] = $row["name"];
        $response["article".$row["article_id"]]["description"] = $row["description"];
        $response["article".$row["article_id"]]["quantity"] = $row["quantity"];
        $response["article".$row["article_id"]]["price"] = $row["price"];
    }
    echo json_encode($response);

    $fp = fopen('results.json', 'w');
    fwrite($fp, json_encode($response));
    fclose($fp);

} else {
    $response["error"] = TRUE;
    $response["error_msg"] = "Error";
    echo json_encode($response);
}
?>

执行 php 时得到的 JSON :

{
  "error": false,
  "article1": {
    "article_id": "1",
    "picture_url": "https://static.webshopapp.com/shops/019852/files/024106649/600x600x2/brasserie-dachouffe-la-chouffe-33cl.jpg",
    "name": "Chouffe",
    "description": "Ceci est une description de la chouffe.",
    "quantity": "33",
    "price": "2.54"
  },
  "article2": {
    "article_id": "2",
    "picture_url": "https://www.latelierdesbieres.fr/1266-large_default/biere-belge-noel-n-ice-chouffe-33-cl.jpg",
    "name": "Chouffe de Noel",
    "description": "Ceci est une description de la chouffe de Noel.",
    "quantity": "33",
    "price": "3.23"
  }
}

您误解了某些异步执行顺序。

您需要重写您的方法以等待返回结果,而不是在不让网络调用完成的情况下立即记录列表大小两次

getArticles(new VolleyCallback() {
    @Override
    public void onSuccessResponse(String result) {
        // parse result 
        // print list size <-- shouldn't be empty 
    } 
});
// your list will be empty here still

其中方法定义为

public void getArticles(VolleyCallback  vcb) {
    getResponse(Request.Method.GET, AppConfig.URL_ARTICLE, null, vcb);
}

但是,当您可以直接使用正确的参数

调用 getResponse 时,包装两个方法似乎毫无意义