I'm trying to do an application that display some article stored in a SQLite database
.
I use a php function on my server to get a JSON file containing my database. In my Android app I want to get that JSON and put it in a JSONObject
, I did the following :
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);
}
But in the Log, the size of mDataset
is always 0. Or if I Log for example the name of the article in onResponse()
I can see every name is in the database. (thus the connection and php function are alright I think)
Any idea ?
Here is the php file :
<?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);
}
?>
And the JSON I get when executing the 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"
}
}
You're misunderstanding some asynchronous execution ordering.
You need to rewrite your method to wait for the returned results, not immediately log the list size twice without letting the network call finish
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
Where the method is defined as
public void getArticles(VolleyCallback vcb) {
getResponse(Request.Method.GET, AppConfig.URL_ARTICLE, null, vcb);
}
However, that seems really pointless to wrap two methods when you could just call getResponse
directly with the correct parameters