Android:JSON PARSE:尝试将JSON放入ListView时,NULL对象引用



该应用程序应该从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

最新更新