Запрос JSON с залпом - PullRequest
       11

Запрос JSON с залпом

0 голосов
/ 26 апреля 2018

Я пытаюсь сделать приложение, которое отображает некоторые статьи, хранящиеся в 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);
}
?>

И JSON, который я получаю при выполнении php:

{
  "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"
  }
}

1 Ответ

0 голосов
/ 29 апреля 2018

Вы неправильно понимаете порядок асинхронного выполнения.

Вам нужно переписать ваш метод, чтобы дождаться возвращаемых результатов, а не сразу дважды регистрировать размер списка, не дожидаясь завершения сетевого вызова

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 напрямую с правильными параметрами

...