如何避免此java.lang.NullPointerException?

如何避免此java.lang.NullPointerException?,java,android,nullpointerexception,Java,Android,Nullpointerexception,我必须在安卓系统中制作一个应用程序。我成功地调试了一些bug,但我不理解这一个: FATAL EXCEPTION: main Process: com.example.android.bookapp, PID: 7450 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a nul

我必须在安卓系统中制作一个应用程序。我成功地调试了一些bug,但我不理解这一个:

FATAL EXCEPTION: main
Process: com.example.android.bookapp, PID: 7450  
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' 
on a null object reference
我可以注意到Android Studio设置了一个橙色背景,提醒我代码的某些部分可能会产生java.lang.NullPointerException,但我不知道如何更改以避免这种情况,我甚至不知道为什么在运行我的应用程序时会发生这种错误

这是我的密码:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    /** find the button view, set an onclick listener on it, define & execute the bookListAsyncTask */
    Button searchButton = (Button) findViewById(R.id.search_button);
    searchButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            BookListAsyncTask bookListAsyncTask = new BookListAsyncTask();
            bookListAsyncTask.execute();
        }
    });
}

/**
 * define the URL
 */
public String makeUrl() {
    EditText searchBookEditText = (EditText) findViewById(R.id.search_edit_text);
    String searchBook = searchBookEditText.getText().toString();
    String searchBookModified = searchBook.replaceAll(" ", "+");
    final String REQUEST_URL = "https://www.googleapis.com/books/v1/volumes?q=" + searchBookModified + "&maxResults=3&printType=books";
    return REQUEST_URL;
}

private class BookListAsyncTask extends AsyncTask<URL, Void, ArrayList<Book>> {

    @Override
    protected ArrayList<Book> doInBackground(URL... urls) {
        // Create URL object
        URL url = createUrl(makeUrl());

        // Perform HTTP request to the URL and receive a JSON response back
        String jsonResponse = "";
        try {
            jsonResponse = makeHttpRequest(url);
        } catch (IOException e) {
        }

        // Extract relevant fields from the JSON response and create an ArrayList<Book> object
        ArrayList<Book> allBooks = extractFeatureFromJson(jsonResponse);

        return allBooks;
    }

    /**
     * Update the screen with the given books (which was the result of the
     * {@link BookListAsyncTask}).
     */
    @Override
    protected void onPostExecute(ArrayList<Book> allBooks) {
        if (allBooks == null) {
            return;
        }
        BookAdapter bookAdapter = new BookAdapter(MainActivity.this, allBooks);
        ListView listView = (ListView) findViewById(R.id.list_view);
        listView.setAdapter(bookAdapter);
    }

    /**
     * Returns new URL object from the given string URL.
     */
    private URL createUrl(String stringUrl) {
        URL url = null;
        try {
            url = new URL(stringUrl);
        } catch (MalformedURLException exception) {
            Log.e("MainActivity", "Error with creating URL", exception);
            return null;
        }
        return url;
    }

    /**
     * Make an HTTP request to the given URL and return a String as the response.
     */
    private String makeHttpRequest(URL url) throws IOException {
        String jsonResponse = "";
        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setReadTimeout(10000 /* milliseconds */);
            urlConnection.setConnectTimeout(15000 /* milliseconds */);
            urlConnection.connect();
            inputStream = urlConnection.getInputStream();
            int responseCode = urlConnection.getResponseCode();
            if (responseCode == 200) {
                jsonResponse = readFromStream(inputStream);
            } else {
                jsonResponse = "";
                Log.e("MainActivity", "error response code" + String.valueOf(responseCode));
            }

        } catch (IOException e) {
            // TODO: Handle the exception
            Log.e("MainActivity", "Problem retrieving the earthquake JSON results", e);

        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (inputStream != null) {
                // function must handle java.io.IOException here
                inputStream.close();
            }
        }
        return jsonResponse;
    }

    /**
     * Convert the {@link InputStream} into a String which contains the
     * whole JSON response from the server.
     */
    private String readFromStream(InputStream inputStream) throws IOException {
        StringBuilder output = new StringBuilder();
        if (inputStream != null) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
            BufferedReader reader = new BufferedReader(inputStreamReader);
            String line = reader.readLine();
            while (line != null) {
                output.append(line);
                line = reader.readLine();
            }
        }
        return output.toString();
    }

    /**
     * Return a book ArrayList
     */
    public ArrayList<Book> extractFeatureFromJson(String bookJSON) {

        ArrayList<Book> allBooks = new ArrayList<>();
        try {
            JSONObject baseJsonResponse = new JSONObject(bookJSON);
            JSONArray items = baseJsonResponse.getJSONArray("items");

            // If there are results in the features array
            if (items.length() > 0) {
                for (int i = 0; i < items.length(); i++)
                // Parse the JSON and fill the allBooks ArrayList)
                {
                    JSONObject currentBook = items.getJSONObject(i);
                    JSONObject currentVolumeInfo = currentBook.getJSONObject("volumeInfo");
                    String currentTitle = currentVolumeInfo.getString("title");
                    String currentFirstAuthor = "Author Unknown";
                    Book book = new Book(currentTitle, currentFirstAuthor);
                    allBooks.add(book);
                }

                return allBooks;
            }
        } catch (JSONException e) {
            Log.e("MainActivity", "Problem parsing the earthquake JSON results", e);
        }
        return null;
    }
}


public class BookAdapter extends ArrayAdapter<Book> {

    public BookAdapter(Activity context, ArrayList<Book> books) {
        super(context, 0, books);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Check if the existing view is being reused, otherwise inflate the view
        View listItemView = convertView;
        if (listItemView == null) {
            listItemView = LayoutInflater.from(getContext()).inflate(
                    R.layout.list_item_view, parent, false);
        }

        Book currentBook = getItem(position);

        TextView title = (TextView) findViewById(R.id.title_text_view);
        title.setText(currentBook.getTitle());

        TextView author = (TextView) findViewById(R.id.author_text_view);
        author.setText(currentBook.getAuthor());

        return listItemView;
    }
}
}
你看到怎么回事了吗?

换行

TextView title = (TextView) findViewById(R.id.title_text_view);
TextView author = (TextView) findViewById(R.id.author_text_view);


在author.setText的正上方。。。由于某种原因,标题或书籍为空。检查您的xml是否有ID作为这样的变量名。告诉行您从哪里得到exception@John3136这方面的问题很多,但这一点与那一点略有不同。希望解决方案对您有效。。请接受答案大家好,谢谢你们的回答。Sonia我按照您的建议通过listItemView.findViewById更改了findViewById,现在可以使用了。非常感谢。你能解释一下为什么它能用吗?我真的不明白,我的标题和作者文本视图仍然可以为空,因为那里没有更多的NullPointerException警报。这个链接将很有用@Alex9494 BookAdapter似乎是MainActivity的内部类。在BookAdapter中调用findViewById时,实际上是在对包含的MainActivity对象调用此方法。由于MainActivity没有任何具有给定id的视图,findViewById返回null。即使它已经有一个具有给定id的视图,findViewById也只会返回它找到的第一个视图的引用。
TextView title = (TextView) findViewById(R.id.title_text_view);
TextView author = (TextView) findViewById(R.id.author_text_view);
TextView title = (TextView) listItemView.findViewById(R.id.title_text_view);   
TextView author = (TextView) listItemView.findViewById(R.id.author_text_view);



 @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // Check if the existing view is being reused, otherwise inflate the view
            View listItemView = convertView;
            if (listItemView == null) {
                listItemView = LayoutInflater.from(getContext()).inflate(
                        R.layout.list_item_view, parent, false);
            }

            Book currentBook = getItem(position);

            TextView title = (TextView) listItemView.findViewById(R.id.title_text_view);
            title.setText(currentBook.getTitle());

            TextView author = (TextView) listItemView.findViewById(R.id.author_text_view);
            author.setText(currentBook.getAuthor());

            return listItemView;
        }