该应用程序应该从Google Books API中解析一些JSON数据(目前为硬编码),并将书籍的数组列表传递给适配器,以将其显示在listView上。我遇到的问题是JSON Parse正在返回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.android.booklisting, PID: 3278
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
at android.widget.ListView.setAdapter(ListView.java:502)
at com.narvin.android.booklisting.MainActivity.updateDisplay(MainActivity.java:113)
at com.narvin.android.booklisting.MainActivity$MyTask.onPostExecute(MainActivity.java:100)
at com.narvin.android.booklisting.MainActivity$MyTask.onPostExecute(MainActivity.java:79)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.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.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
问题是,出于某种原因,BookAdapter adapter = new BookAdapter(this, bookList);
中的一个参数为null
。尝试将bookList
作为参数传递给updateDisplay
并检查是否不是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) {
ArrayList<Book> bookList = BookJSONParser.parseFeed(result);
updateDisplay(bookList);
}
}
protected void updateDisplay(ArrayList<Book> bookList) {
if (bookList != null){
BookAdapter adapter = new BookAdapter(this, bookList);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
}
}
似乎您正在获得JSONPARSEEXCEPTION ...因此,将列表的nullpoInterexpcetion置于适配器
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
那是您的错误,这是您获得的方式
public static ArrayList<Book> parseFeed(String content) {
try {
JSONArray jsonArray = new JSONArray(content); // <-- Throws an error
ArrayList<Book> bookList = new ArrayList<>();
// Stuff...
return bookList;
} catch (JSONException e) {
e.printStackTrace();
return null; // <----- Null is returned
}
您在这里使用该空值
@Override
protected void onPostExecute(String result) {
bookList = BookJSONParser.parseFeed(result);
updateDisplay();
}
接着
protected void updateDisplay() {
BookAdapter adapter = new BookAdapter(this, bookList); // <-- Null here
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
因此,修复NullPoInterExpception的方法是始终返回arraylist
ArrayList<Book> bookList = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(content);
// Stuff...
} catch (JSONException e) {
e.printStackTrace();
}
return bookList;
要从URL获取JSON字符串,您应该像那样做
String content = new MyTask()
.execute("https://www.googleapis.com/books/v1/volumes?q=millionare")
.get();
//pass the content to BookJSONParser class
booklist = new BookJSONParser().parseFeed(content);
updateDisplay();
您从提供的URL中获得的不是jsonarray,而是一个jsonobject因此,我认为此代码将"假设您正确地完成其他所有操作"
JSONObject o = new JSONObject(content);
JSONArray jsonArray = o.getJSONArray("items");
您可以做for loop