Запрос JSON с залпом
Я пытаюсь сделать приложение, которое отображает некоторые статьи, хранящиеся в 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 ответ
Вы неправильно понимаете порядок асинхронного выполнения.
Вам нужно переписать свой метод, чтобы дождаться возвращаемых результатов, а не сразу дважды регистрировать размер списка, не давая завершить сетевой вызов
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
непосредственно с правильными параметрами