尝试将JSON解析为ListView时的Android:JSON parse:null对象引用
这个应用程序应该解析来自GoogleBooksAPI的一些JSON数据(目前为硬编码),并将书籍的ArrayList传递给适配器,适配器将在ListView上显示它。我遇到的问题是,JSON解析返回的是null,而不是解析的数据
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
ProgressBar pBar;
List<MyTask> tasks;
ArrayList<Book> bookList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pBar = (ProgressBar) findViewById(R.id.progressBar);
pBar.setVisibility(View.INVISIBLE);
Button sButton = (Button) findViewById(R.id.s_button);
sButton.setOnClickListener(this);
tasks = new ArrayList<>();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.s_button: {
if (isOnline()) {
new MyTask().execute("https://www.googleapis.com/books/v1/volumes?q=millionare"); //https://www.googleapis.com/books/v1/volumes?q=soft+skills
} else {
Toast.makeText(this, "Connection failed", Toast.LENGTH_LONG).show();
}
break;
}
}
}
protected boolean isOnline() {
ConnectivityManager connectManager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = connectManager.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else {
return false;
}
}
private class MyTask extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return HttpManager.getData(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
@Override
protected void onPostExecute(String result) {
bookList = BookJSONParser.parseFeed(result);
updateDisplay();
}
}
protected void updateDisplay() {
BookAdapter adapter = new BookAdapter(this, bookList);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
}
public class BookJSONParser {
public static ArrayList<Book> parseFeed(String content) {
try {
JSONArray jsonArray = new JSONArray(content);
ArrayList<Book> bookList = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String name = object.getString("title").toString();
Book book = new Book(name);
bookList.add(book);
}
return bookList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
}
public class BookAdapter extends ArrayAdapter<Book> {
public BookAdapter(Context context, ArrayList<Book> bookList) {
super(context, 0, bookList);
}
@Override
public View getView(int position, View convertedView, ViewGroup parent) {
View listItemView = convertedView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Book currentBook = getItem(position);
TextView locationName = (TextView) listItemView.findViewById(R.id.book_title);
locationName.setText(currentBook.getTittle());
TextView locationAddress = (TextView) listItemView.findViewById(R.id.book_author);
locationAddress.setText(currentBook.getAuthor());
return listItemView;
}
}
public class HttpManager {
public static String getData(String myUrl) throws IOException {
// BufferedReader reader = null;
InputStream inputStream = null;
int len = 10000;
try {
URL url = new URL(myUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(10000 /* milliseconds */);
connection.setConnectTimeout(15000 /* milliseconds */);
connection.setRequestMethod("GET");
connection.setDoInput(true);
// Starts the query
connection.connect();
int response = connection.getResponseCode();
inputStream = connection.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(inputStream, len);
return contentAsString;
// Makes sure that the InputStream inputStream closed after the app inputStream
// finished using it.
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}
// Reads an InputStream and converts it to a String.
public static String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
}
public class Book {
private String mTittle;
/**
* This is the constructor.
* @param title is the book title being passed in.
*/
public Book(String title) {
mTittle = title;
}
public String getTittle() {
return mTittle;
}
public void setTittle(String tittle) {
mTittle = tittle;
}
}
FATAL EXCEPTION: main
Process: com.narvin.安卓.booklisting, PID: 3278
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at 安卓.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
at 安卓.widget.ListView.setAdapter(ListView.java:502)
at com.narvin.安卓.booklisting.MainActivity.updateDisplay(MainActivity.java:113)
at com.narvin.安卓.booklisting.MainActivity$MyTask.onPostExecute(MainActivity.java:100)
at com.narvin.安卓.booklisting.MainActivity$MyTask.onPostExecute(MainActivity.java:79)
at 安卓.os.AsyncTask.finish(AsyncTask.java:632)
at 安卓.os.AsyncTask.access$600(AsyncTask.java:177)
at 安卓.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at 安卓.os.Handler.dispatchMessage(Handler.java:102)
at 安卓.os.Looper.loop(Looper.java:145)
at 安卓.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
# 1 楼答案
要从url获取json字符串,您应该这样做
从提供的url中得到的不是jsonArray,而是jsonobject 因此,我认为这段代码“假设您正确地完成了所有其他操作”会起作用
您可以执行for循环
# 2 楼答案
您似乎收到了一个JSONParseException。。。因此,导致将列表的NullPointerExpection插入适配器
这是你的错误,下面是你如何得到它的
这里使用空值
接
因此,修复NullPointerExpection的方法是始终返回ArrayList
# 3 楼答案
问题是
BookAdapter adapter = new BookAdapter(this, bookList);
中的一个参数出于某种原因是null
。尝试将bookList
作为参数传递给updateDisplay
,并检查它是否为null