解析 JSON 并在 Listview 中显示检索/获取 URL 服务器“无数据”
Posted
技术标签:
【中文标题】解析 JSON 并在 Listview 中显示检索/获取 URL 服务器“无数据”【英文标题】:Parse JSON And Show In Listview Retrieve/Fetch URL Server " No Data " 【发布时间】:2019-07-26 20:01:33 【问题描述】:我在 android 中从 JSON 解析到 Listview 时遇到问题。这是来自 JSON 的数据示例:
"status":
"statusCode": 200,
"success": true,
"message": "Success"
,
"demandes": [
"id": "1",
"dateCreation": "21/01/2014",
"tagDemand": "xxxxxxxxxxxx",
"descDemande": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"imageUrl": "https://picsum.photos/3800/50/?image=1"
,
"id": "2",
"dateCreation": "15/01/2017",
"tagDemand": "yyyyyyyyyyyyyyyyyyyy",
"descDemande": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
"imageUrl": "https://picsum.photos/3500/5200/?image=221"
]
这是主要活动:
public class MyRequests extends AppCompatActivity
private String jsonURL = "https://26ae7d0d-62b2-4cc4-8ff7-009bee255089.mock.pstmn.io/demands";
private final int jsoncode = 1;
private ListView listView;
ArrayList<DemandeModel> demandeModelArrayList;
private DemandeAdapter demandeAdapter;
String response = "";
private static ProgressDialog mProgressDialog;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_requests);
listView = findViewById(R.id.lv);
fetchJSON();
@SuppressLint("StaticFieldLeak")
private void fetchJSON()
showSimpleProgressDialog(this, "Chargement...", "Récupération des données", false);
new AsyncTask<Void, Void, String>()
protected String doInBackground(Void[] params)
// String response="";
HashMap<String, String> map = new HashMap<>();
try
HttpRequest req = new HttpRequest(jsonURL);
response = req.prepare(HttpRequest.Method.POST).withData(map).sendAndReadString();
catch (Exception e)
response = e.getMessage();
return response;
protected void onPostExecute(String result)
//do something with response
Log.d("newwwss", result);
onTaskCompleted(result, jsoncode);
.execute();
public void onTaskCompleted(String response, int serviceCode)
Log.d("responsejson", response.toString());
switch (serviceCode)
case jsoncode:
if (isSuccess(response))
removeSimpleProgressDialog(); //will remove progress dialog
demandeModelArrayList = getInfo(response);
demandeAdapter = new DemandeAdapter(this, demandeModelArrayList);
listView.setAdapter(demandeAdapter);
else
Toast.makeText(MyRequests.this, getErrorCode(response), Toast.LENGTH_SHORT).show();
public ArrayList<DemandeModel> getInfo(String response)
ArrayList<DemandeModel> demandeModelArrayList = new ArrayList<>();
try
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getJSONObject("status").optString("success").equals("true"))
JSONArray dataArray = jsonObject.getJSONArray("demandes");
for (int i = 0; i < dataArray.length(); i++)
DemandeModel playersModel = new DemandeModel();
JSONObject dataobj = dataArray.getJSONObject(i);
playersModel.setId(dataobj.getString("id"));
playersModel.setDate(dataobj.getString("dateCreation"));
playersModel.setNom(dataobj.getString("tagDemand"));
playersModel.setDescription(dataobj.getString("descDemande"));
playersModel.setImgURL(dataobj.getString("imageUrl"));
demandeModelArrayList.add(playersModel);
catch (JSONException e)
e.printStackTrace();
return demandeModelArrayList;
public boolean isSuccess(String response)
try
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getJSONObject("status").optString("success").equals("true"))
return true;
else
return false;
catch (JSONException e)
e.printStackTrace();
return false;
public String getErrorCode(String response)
try
JSONObject jsonObject = new JSONObject(response);
return jsonObject.getJSONObject("status").optString("message");
catch (JSONException e)
e.printStackTrace();
return "No data";
public static void removeSimpleProgressDialog()
try
if (mProgressDialog != null)
if (mProgressDialog.isShowing())
mProgressDialog.dismiss();
mProgressDialog = null;
catch (IllegalArgumentException ie)
ie.printStackTrace();
catch (RuntimeException re)
re.printStackTrace();
catch (Exception e)
e.printStackTrace();
public static void showSimpleProgressDialog(Context context, String title,
String msg, boolean isCancelable)
try
if (mProgressDialog == null)
mProgressDialog = ProgressDialog.show(context, title, msg);
mProgressDialog.setCancelable(isCancelable);
if (!mProgressDialog.isShowing())
mProgressDialog.show();
catch (IllegalArgumentException ie)
ie.printStackTrace();
catch (RuntimeException re)
re.printStackTrace();
catch (Exception e)
e.printStackTrace();
所以,我有一个响应“没有数据”,所以我认为这里有问题“if (isSuccess(response))”
这是我的适配器:
public class DemandeAdapter extends BaseAdapter
private Context context;
private ArrayList<DemandeModel> demandeModelArrayList;
public DemandeAdapter(Context context, ArrayList<DemandeModel> demandeModelArrayList)
this.context = context;
this.demandeModelArrayList = demandeModelArrayList;
@Override
public int getViewTypeCount()
return getCount();
@Override
public int getItemViewType(int position)
return position;
@Override
public int getCount()
return demandeModelArrayList.size();
@Override
public Object getItem(int position)
return demandeModelArrayList.get(position);
@Override
public long getItemId(int position)
return 0;
@Override
public View getView(int position, View convertView, ViewGroup parent)
ViewHolder holder;
if (convertView == null)
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.demande, null, true);
holder.iv = (ImageView) convertView.findViewById(R.id.iv);
holder.id = (TextView) convertView.findViewById(R.id.id);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.desc = (TextView) convertView.findViewById(R.id.desc);
holder.date = (TextView) convertView.findViewById(R.id.date);
convertView.setTag(holder);
else
// the getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)convertView.getTag();
Picasso.get().load(demandeModelArrayList.get(position).getImgURL()).into(holder.iv);
holder.id.setText("ID : "+demandeModelArrayList.get(position).getId());
holder.date.setText("Date : "+demandeModelArrayList.get(position).getDate());
holder.name.setText("Name : "+demandeModelArrayList.get(position).getNom());
holder.desc.setText("Description : "+demandeModelArrayList.get(position).getDescription());
return convertView;
private class ViewHolder
protected TextView id,name,desc,date;
protected ImageView iv;
这是我的模型:
public class DemandeModel
private String id;
private String nom;
private String description;
private String date;
private String imgURL;
public DemandeModel()
public DemandeModel(String id, String nom, String description, String date, String imgURL)
this.id = id;
this.nom = nom;
this.description = description;
this.date = date;
this.imgURL = imgURL;
public String getId()
return id;
public void setId(String id)
this.id = id;
public String getNom()
return nom;
public void setNom(String nom)
this.nom = nom;
public String getDescription()
return description;
public void setDescription(String description)
this.description = description;
public String getDate()
return date;
public void setDate(String date)
this.date = date;
public String getImgURL()
return imgURL;
public void setImgURL(String imgURL)
this.imgURL = imgURL;
这是 HttpRequest :
public class HttpRequest
public static enum Method
POST, PUT, DELETE, GET;
private URL url;
private HttpURLConnection con;
private OutputStream os;
//After instantiation, when opening connection - IOException can occur
public HttpRequest(URL url) throws IOException
this.url = url;
con = (HttpURLConnection) this.url.openConnection();
//Can be instantiated with String representation of url, force caller to check for IOException which can be thrown
public HttpRequest(String url) throws IOException
this(new URL(url));
Log.d("parameters", url);
/**
* Sending connection and opening an output stream to server by pre-defined instance variable url
*
* @param //isPost boolean - indicates whether this request should be sent in POST method
* @throws IOException - should be checked by caller
*/
private void prepareAll(Method method) throws IOException
con.setDoInput(true);
con.setRequestMethod(method.name());
if (method == Method.POST || method == Method.PUT)
con.setDoOutput(true);
os = con.getOutputStream();
//prepare request in GET method
//@return HttpRequest this instance -> for chaining method @see line 22
public HttpRequest prepare() throws IOException
prepareAll(Method.GET);
return this;
/**
* Prepares HttpRequest method with for given method, possible values: HttpRequest.Method.POST,
* HttpRequest.Method.PUT, HttpRequest.Method.GET & HttpRequest.Method.DELETE
*
* @param method HttpRequest.Method - nested enum HttpRequest.Method constant
* @return HttpRequest this instance -> for chaining method @see line 22
* @throws IOException - should be checked by caller
*/
public HttpRequest prepare(Method method) throws IOException
prepareAll(method);
return this;
/**
* Adding request headers (standard format "Key":"Value")
*
* @param headers String variadic params in standard format "Key":"Value"
* @return HttpRequest this instance -> for chaining method @see line 22
*/
public HttpRequest withHeaders(String... headers)
for (int i = 0, last = headers.length; i < last; i++)
String[] h = headers[i].split("[:]");
con.setRequestProperty(h[0], h[1]);
return this;
/**
* Writes query to open stream to server
*
* @param query String params in format of key1=v1&key2=v2 to open stream to server
* @return HttpRequest this instance -> for chaining method @see line 22
* @throws IOException - should be checked by caller
*/
public HttpRequest withData(String query) throws IOException
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.close();
return this;
/**
* Builds query on format of key1=v1&key2=v2 from given hashMap structure
* for map: name=Bubu, age=29 -> builds "name=Bubu&age=29"
* for map: Iam=Groot -> builds "Iam=Groot"
*
* @param params HashMap consists of key-> value pairs to build query from
* @return HttpRequest this instance -> for chaining method @see line 22
* @throws IOException - should be checked by caller
*/
public HttpRequest withData(HashMap<String, String> params) throws IOException
StringBuilder result = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet())
result.append((result.length() > 0 ? "&" : "") + entry.getKey() + "=" + entry.getValue());//appends: key=value (for first param) OR &key=value(second and more)
Log.d("parameters", entry.getKey() + " ===> " + entry.getValue());
withData(result.toString());
return this;
//When caller only need to send, and don't need String response from server
public int send() throws IOException
return con.getResponseCode(); //return HTTP status code to indicate whether it successfully sent
/**
* Sending request to the server and pass to caller String as it received in response from server
*
* @return String printed from server's response
* @throws IOException - should be checked by caller
*/
public String sendAndReadString() throws IOException
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder response = new StringBuilder();
for (String line; (line = br.readLine()) != null; ) response.append(line + "\n");
Log.d("ressss", response.toString());
return response.toString();
/**
* Sending request to the server and pass to caller its raw contents in bytes as it received from server.
*
* @return byte[] from server's response
* @throws IOException - should be checked by caller
*/
public byte[] sendAndReadBytes() throws IOException
byte[] buffer = new byte[8192];
InputStream is = con.getInputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream();
for (int bytesRead; (bytesRead = is.read(buffer)) >= 0; ) output.write(buffer, 0, bytesRead);
return output.toByteArray();
//JSONObject representation of String response from server
public JSONObject sendAndReadJSON() throws JSONException, IOException
return new JSONObject(sendAndReadString());
如果有人可以帮助解决这个问题,那将很高兴
【问题讨论】:
【参考方案1】:我已经更新了解析方法。检查下面
public ArrayList<DemandeModel> getInfo(String response)
ArrayList<DemandeModel> demandeModelArrayList = new ArrayList<>();
try
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getJSONObject("status").optString("success").equals("true"))
JSONArray dataArray = jsonObject.getJSONArray("demandes");
for (int i = 0; i < dataArray.length(); i++)
DemandeModel playersModel = new DemandeModel();
JSONObject dataobj = dataArray.getJSONObject(i);
playersModel.setId(dataobj.getString("id"));
playersModel.setDate(dataobj.getString("dateCreation"));
playersModel.setNom(dataobj.getString("tagDemand"));
playersModel.setDescription(dataobj.getString("descDemande"));
playersModel.setImgURL(dataobj.getString("imageUrl"));
demandeModelArrayList.add(playersModel);
catch (JSONException e)
e.printStackTrace();
return demandeModelArrayList;
EDIT下面的方法更新了一点
public boolean isSuccess(String response)
try
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getJSONObject("status").optString("success").equals("true"))
return true;
else
return false;
catch (JSONException e)
e.printStackTrace();
return false;
编辑 2
更改下一行
response = req.prepare(HttpRequest.Method.POST).withData(map).sendAndReadString();
到
response = req.prepare().sendAndReadString();
【讨论】:
评论不用于扩展讨论;这个对话是moved to chat。【参考方案2】:您似乎在读取错误的数据:
jsonObject.getString("status").equals("true")
您的 json respose 示例中没有“状态”。有“成功”。
【讨论】:
是的,你是对的,我会尝试 if (jsonObject.getJSONObject("status").getString("success").equals("true")) 我没有找到解决办法,你觉得呢?以上是关于解析 JSON 并在 Listview 中显示检索/获取 URL 服务器“无数据”的主要内容,如果未能解决你的问题,请参考以下文章
解析来自 JSON 服务器的数据时,Android ListView 不显示