使用 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
时,包装两个方法似乎毫无意义
我正在尝试做一个显示存储在 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
时,包装两个方法似乎毫无意义