解析来自 JSON 服务器的数据时,Android ListView 不显示
Posted
技术标签:
【中文标题】解析来自 JSON 服务器的数据时,Android ListView 不显示【英文标题】:Android ListView not showing while parsing data from JSON server 【发布时间】:2015-11-24 02:08:07 【问题描述】:所以我正在测试一个在 listview 上实现的 android 应用程序。该列表使用从 JSON 服务器获取的数据。视图中使用的三个字段是图像、名称、描述。我已经测试了所有输入,数据正确来自服务器,在适配器中设置(使用 LOG 标签检查),但应用程序没有显示任何视图,有时甚至崩溃。总之,我看不到任何列表视图。请帮忙... :)
这些是我的项目使用的文件...
MainActivity.java
package com.example.aditya.jtest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
import android.widget.Toast;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
public class MainActivity extends Activity
ListView list;
ActorsAdapter adapter;
ArrayList<Actors> actorsList;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView) findViewById(R.id.list);
actorsList = new ArrayList<Actors>();
new ActorsAsynTask().execute("http://microblogging.wingnity.com/JSONParsingTutorial/ `jsonActors");
list.setAdapter(adapter);
public class ActorsAsynTask extends AsyncTask<String, Void, Boolean>
ProgressDialog dialog;
@Override
protected void onPreExecute()
super.onPreExecute();
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("Loading, please wait");
dialog.setTitle("Connecting server");
dialog.show();
dialog.setCancelable(false);
@Override
protected Boolean doInBackground(String... params)
try
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(params[0]);
HttpResponse response = client.execute(post);
int status = response.getStatusLine().getStatusCode();
//Log.d("MyFilter2", "" + status + " Value Recieved: " + params[0]);
if (status == 200)
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
//Log.d("MyFilter", data);
JSONObject jObj = new JSONObject(data);
JSONArray jArray = jObj.getJSONArray("actors");
//Log.d("MyFilterjObj: ", jObj.toString());
//Log.d("MyFilterjArray: ", jArray.toString() + "\n" + jArray.length());
for(int i = 0; i <= jArray.length(); i++)
Actors actors = new Actors();
JSONObject jRealObject = jArray.getJSONObject(i);
//Log.d("\nMyFilter JRealObject[" + i + "]: ", jRealObject.toString());
actors.setName(jRealObject.getString("name"));
actors.setDescription(jRealObject.getString("description"));
actors.setImage(jRealObject.getString("image"));
Log.d("\nMyFilter ["+ i +"]", jRealObject.getString("name"));
Log.d("MyFilter ["+ i +"]", jRealObject.getString("description"));
Log.d("MyFilter ["+ i +"]", jRealObject.getString("image"));
actorsList.add(actors);
return true;
catch (IOException e)
e.printStackTrace();
catch (JSONException e)
e.printStackTrace();
return false;
@Override
protected void onPostExecute(Boolean aBoolean)
super.onPostExecute(aBoolean);
dialog.cancel();
adapter.notifyDataSetChanged();
if(aBoolean == false)
//Show a message that data was not parsed
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
Actor 适配器
package com.example.aditya.jtest;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ActorsAdapter extends ArrayAdapter<Actors>
ArrayList<Actors> ArrayListActors;
int Resource;
Context context;
LayoutInflater vi;
ViewHolder holder;
public ActorsAdapter(Context context, int resource, ArrayList<Actors> objects)
super(context, R.layout.row, objects);
ArrayListActors = objects;
Resource = resource;
this.context = context;
@Override
public View getView(int position, View convertView, ViewGroup parent)
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = convertView;
if(v == null)
v = vi.inflate(Resource, null);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.image);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.description = (TextView) convertView.findViewById(R.id.description);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
new DownloadImageTask(holder.image).execute(ArrayListActors.get(position).getImage());
holder.name.setText(ArrayListActors.get(position).getName());
holder.description .setText(ArrayListActors.get(position).getDescription());
return v;
static class ViewHolder
public ImageView image;
public TextView name;
public TextView description;
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
ImageView bmImage;
public DownloadImageTask(ImageView bmImage)
this.bmImage = bmImage;
@Override
protected Bitmap doInBackground(String... params)
String urlDisplay = params[0];
Bitmap mIcon1 = null;
try
InputStream in = new java.net.URL(urlDisplay).openStream();
mIcon1 = BitmapFactory.decodeStream(in);
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
return mIcon1;
@Override
protected void onPostExecute(Bitmap bitmap)
bmImage.setImageBitmap(bitmap);
Actors.java
package com.example.aditya.jtest;
public class Actors
private String image;
private String name;
private String description;
public Actors()
public Actors(String name, String description, String image)
super();
this.name = name;
this.description = description;
this.image = image;
public String getImage()
return image;
public void setImage(String image)
this.image = image;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getDescription()
return description;
public void setDescription(String description)
this.description = description;
【问题讨论】:
了解如何从服务器获取数据并设置列表视图here。 你的网址有效吗? 是的.. URL 正在工作...!! 【参考方案1】:添加 onPostExecute()
的 ActorsAsynTask。
adapter = new ActorsAdapter(MainActivity.this, /*Your resource file id*/,actorsList);
list.setAdapter(adapter)
这样就可以了。
【讨论】:
不……不工作……应用程序崩溃了……一个问题 - 布局是否与它有任何关系……?? 我不这么认为..您只需要初始化适配器并将其设置为 onPostExecute() 中的列表视图。否则它将在后台进程完成之前执行,并且您可能有空列表视图或部分膨胀的列表视图。 不!......再次无法正常工作。我在 onPostExecute() 的“else”块中添加了上述两行。应用程序仍在崩溃... :( 在其他地方做。并告诉我 logcat 对错误的描述。 将代码移到其他地方......这是日志错误......进程:com.example.aditya.jtest,PID:4703 java.lang.NullPointerException at com.example .aditya.jtest.MainActivity$ActorsAsynTask.onPostExecute(MainActivity.java:110) 在 com.example.aditya.jtest.MainActivity$ActorsAsynTask.onPostExecute(MainActivity.java:44) 在 android.os.AsyncTask.finish(AsyncTask.java :632) 在 android.os.AsyncTask.access$600(AsyncTask.java:177)【参考方案2】: import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.Toast;
public class PrivateJobList extends Fragment
/**Declaring the data members **/
List<PrivateData> list;
PrivateJobListAdapter adapter;
ListView listview;
PrivateJobList()
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View v=inflater.inflate(R.layout.private_job_list,container,false);
listview=(ListView)v.findViewById(R.id.list);
/*converting or say initializing list as arraylist*/
list=new ArrayList<PrivateData>();
/*instantiating the class which deals with fetching*/
ExecuteTaskprivate executetask= new ExecuteTaskprivate();
/*calling execute method on class instance*/
executetask.execute();
/*initializing the adapter*/
adapter = new PrivateJobListAdapter(getActivity(),list);
return v;
/*class to handle background task*/
class ExecuteTaskprivate extends AsyncTask<String, Void,String>
@Override
protected String doInBackground(String... params)
/**storing returned value from this method in res variable
* and pass it to the postData method**/
String res=postData(params);
return res;
/**This method Deals with the posting the client request
* and storing the response in String variable which is
* nothing but a HttpResponse from the server**/
private String postData(String[] params)
String s="";
try
HttpClient httpClient=new DefaultHttpClient();
HttpPost httpPost=new HttpPost("http://10.0.2.2/loginpage/private_jobs_fetching.php");
HttpResponse res= httpClient.execute(httpPost);
@SuppressWarnings("unused")
HttpEntity httpEntity=res.getEntity();
s= readResponse(res);
catch(Exception exception)
return s;
/**this method returns String representation of response from server**/
private String readResponse(HttpResponse res)
String return_text="";
InputStream is = null;
try
is=res.getEntity().getContent();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(is,"utf-8"),8);
String line="";
StringBuffer sb=new StringBuffer();
while ((line=bufferedReader.readLine())!=null)
sb.append(line);
return_text=sb.toString();
catch (Exception e)
e.printStackTrace();
return return_text;
/**In onPostExecute String variable returned from doInBackground is used as parameter**/
@Override
protected void onPostExecute(String result)
super.onPostExecute(result);
if(result.length()!=0)
try
/**parsing JSONArray first**/
JSONArray jArray = new JSONArray(result);
/**looping through it's length**/
for (int i = 0; i<jArray.length();i++)
/**And converting it to the JSONObject**/
JSONObject json_data = jArray.getJSONObject(i);
/**Creating instance of Bean class**/
PrivateData user= new PrivateData();
/**fetching data directly from server by providing column names
* and setting to their respective setter method's of bean class**/
user.setCompany_name(json_data.getString("company_name"));
user.setJob_title(json_data.getString("job_title"));
user.setLocation(json_data.getString("location"));
user.setEmail(json_data.getString("email"));
user.setUid(json_data.getInt("uid"));
/**Adding PrivateData object to the list**/
list.add(user);
/**setting the adapter on listview**/
listview.setAdapter(adapter);
catch (JSONException e)
Log.e("log_tag", "Error parsing data " + e.toString());
else
Toast.makeText(getActivity(), result, Toast.LENGTH_SHORT).show();
/**************************************************** *****************************/
/**Bean class with data members & their respective setter & getters**/
public class PrivateData
String company_name;
String job_title;
String location;
String email;
int uid;
public String getCompany_name()
return company_name;
public void setCompany_name(String company_name)
this.company_name = company_name;
public String getJob_title()
return job_title;
public void setJob_title(String job_title)
this.job_title = job_title;
public String getLocation()
return location;
public void setLocation(String location)
this.location = location;
public String getEmail()
return email;
public void setEmail(String email)
this.email = email;
public int getUid()
return uid;
public void setUid(int uid)
this.uid = uid;
/**************************************************** ************************************/
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
/**ListAdapter class**/
public class PrivateJobListAdapter extends ArrayAdapter<PrivateData>
/**data members**/
Context c;
//int layout;
List<PrivateData> list;
/**Constructor**/
public PrivateJobListAdapter(Context context,List<PrivateData> objects)
super(context,R.layout.row_view, objects);
this.c=context;
this.list=objects;
/**this method is used to display your fetched data from server **/
@Override
public View getView(int position, View convertView, ViewGroup parent)
View row = convertView;
/**initializing class which has all textview required for showing column data
* of table on server**/
UserHolder holder = null;
if(row==null)
/**this is important step if your main class is an Activity
* then write it as
* LayoutInflater inflater = ((Activity) context).getLayoutInflater();
* and import android.app.activity**/
LayoutInflater inflater= LayoutInflater.from(c);
/****/
row = inflater.inflate(R.layout.row_view, parent, false);
holder = new UserHolder();
holder.textcompanyname=(TextView) row.findViewById(R.id.textview_company_name);
holder.textjobtitle=(TextView) row.findViewById(R.id.textview_job_title);
holder.textlocation=(TextView) row.findViewById(R.id.textview_location);
holder.textemail=(TextView) row.findViewById(R.id.textview_email);
/**setting tag**/
row.setTag(holder);
else
/**getting tag**/
holder = (UserHolder) row.getTag();
return row;
static class UserHolder
TextView textcompanyname;
TextView textjobtitle;
TextView textlocation;
TextView textemail;
/**************************************************** ******/
//private_job_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<TextView android:id="@+id/textview_private_job_list"
android:layout_
android:layout_
android:background="@drawable/button_rounded"
android:layout_marginTop="20dp"
android:layout_marginStart="32dp"
android:text="@string/private_job_list_text"
android:textSize="20sp"
android:gravity="center"/>
<ListView
android:id="@+id/list"
android:layout_
android:layout_></ListView>
</LinearLayout>
/**********************************************/
//row-view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_ >
<TextView
android:id="@+id/textview_company_name"
android:layout_
android:layout_
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:text="@string/company_name"
android:textSize="18sp"/>
<TextView
android:id="@+id/textview_job_title"
android:layout_
android:layout_
android:layout_alignParentStart="true"
android:layout_below="@+id/textview_company_name"
android:layout_marginTop="5dp"
android:text="@string/job_title"
android:textSize="18sp" />
<Button
android:id="@+id/button_more"
android:layout_
android:layout_
android:layout_alignParentEnd="true"
android:layout_marginTop="40dp"
android:background="@drawable/button_rounded"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="@string/btn_more"
android:textColor="#0099CC" />
<TextView
android:id="@+id/textview_location"
android:layout_
android:layout_
android:layout_alignParentStart="true"
android:layout_below="@+id/textview_job_title"
android:layout_marginTop="5dp"
android:text="@string/location"
android:textSize="18sp"/>
<TextView
android:id="@+id/textview_email"
android:layout_
android:layout_
android:layout_alignParentStart="true"
android:layout_below="@+id/textview_location"
android:layout_marginTop="5dp"
android:text="@string/email"
android:textSize="18sp" />
</RelativeLayout>
/************************************************/
//button_rounded.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#ec0b47"/>
<corners
android:radius="30dp"/>
</shape>
/****************************************/
//php code
<?php
$host='localhost:3306';
$uname='root';
$pwd='';
$db="mydb";
$connection=mysqli_connect($host,$uname,$pwd,$db);
$database=mysqli_select_db($connection,$db);
$query1=mysqli_query($connection,"SELECT * FROM private_jobs");
while($row=mysqli_fetch_assoc($query1))
$result[]=$row;
print(json_encode($result));
mysqli_close($connection);
?>
happy coding!!!!
【讨论】:
以上是关于解析来自 JSON 服务器的数据时,Android ListView 不显示的主要内容,如果未能解决你的问题,请参考以下文章
解析 JSON 并在 Listview 中显示检索/获取 URL 服务器“无数据”
Android:如何让我检索到的(来自 mysql)JSON 解析数据添加到 ListView 每分钟刷新一次
Android – 使用带有 Jetpack Compose 的 Retrofit 库进行 JSON 解析