有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

尝试将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)

共 (3) 个答案

  1. # 1 楼答案

    要从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循环

  2. # 2 楼答案

    您似乎收到了一个JSONParseException。。。因此,导致将列表的NullPointerExpection插入适配器

    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);
    }
    

    因此,修复NullPointerExpection的方法是始终返回ArrayList

    ArrayList<Book> bookList = new ArrayList<>();
    try {
        JSONArray jsonArray = new JSONArray(content);
    
        // Stuff...
    } catch (JSONException e) {
        e.printStackTrace();
    }
    
    return bookList;
    
  3. # 3 楼答案

    问题是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);
         }
    }
    }