【问题标题】:why ListView does not filled while I am using AsyncTask?为什么我在使用 AsyncTask 时没有填充 ListView?
【发布时间】:2019-09-28 08:26:20
【问题描述】:

我正在编写一个使用 Google 图书搜索 API 的应用程序,该应用程序要做的是根据我在应用程序代码中作为字符串提供的搜索查询显示图书列表,我使用 AsyncTask 内部类为了处理后台工作(发出 HTTP 请求、JSON 格式等),我还有书籍服装适配器和书籍类来获取数据,我的问题是应用程序没有在列表视图中显示任何书籍。

这是我的代码:

我的活动:

public class MainActivity extends AppCompatActivity {

    final static String bookUrl = "https://www.googleapis.com/books/v1/volumes?q=android&maxResults=6";
    private BookAdapter bookAdapter;

    private ArrayList<Book> books;

    private ListView list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


         list = (ListView) findViewById(R.id.list);
         new BookAsynck().execute(bookUrl);


    }

    private class BookAsynck extends AsyncTask<String, Void, ArrayList<Book>> {
        @Override
        protected ArrayList<Book> doInBackground(String... strings) {
            books = Utils.fetchBookData(bookUrl);
            return books;
        }

        @Override
        protected void onPostExecute(ArrayList<Book> books) {
            bookAdapter = new BookAdapter(MainActivity.this, books);
            list.setAdapter(bookAdapter);
        }
    }

}

我的 Util 类:

    public class Utils {
    public static final String LOG_TAG = Utils.class.getSimpleName();


    public static ArrayList<Book> fetchBookData(String requestUrl) {

        ArrayList<Book> bookList = new ArrayList<>();

        URL url = CreateURl(requestUrl);
        String json = null;
        try {
            json = makeHttpRequest(url);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error closing input stream", e);
        }
        bookList = extractBookData(json);
        return bookList;
    }


    public static URL CreateURl(String stringUrl) {
        URL url = null;
        try {
            url = new URL(stringUrl);
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Error with creating URL ", e);
        }
        return url;
    }

    //make http  request and return a string containing the response
    public static String makeHttpRequest(URL url) throws IOException {
        String jsonResponse = "";
        //if the url is null return empty string
        if (url == null) {
            return jsonResponse;
        }

        HttpURLConnection urlcon = null;
        InputStream inputstream = null;
        try {
            urlcon = (HttpURLConnection) url.openConnection();
            urlcon.setRequestMethod("GET");
            urlcon.setReadTimeout(1000 /*milleseconds*/);
            urlcon.setConnectTimeout(1500 /*milleseconds*/);
            urlcon.connect();
//if the request wass Successul (code 200)
            // get the input stream and decode it

            if (urlcon.getResponseCode() == 200) {
                inputstream = urlcon.getInputStream();
                jsonResponse = readFromStream(inputstream);
            } else {
                Log.e(LOG_TAG, "Error response code " + urlcon.getResponseCode());

            }
        } catch (IOException e) {
            Log.e(LOG_TAG, "Problem retrieving the book JSON results", e);
        } finally {
            if (urlcon != null) {
                urlcon.disconnect();
            }
            if (inputstream != null) {
                inputstream.close();
            }
        }

        return jsonResponse;
    }


//decode the inputstream into string that conatin the Jsresponse from the Server


        private static 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();
        }

        public static ArrayList<Book> extractBookData(String json) {
            ArrayList<Book> booklist = new ArrayList<>();

            if (TextUtils.isEmpty(json)) {
                return null;
            }

            try {
                JSONObject base = new JSONObject(json);
                JSONArray itemsArray = base.optJSONArray("items");

                for (int i = 0; i < itemsArray.length(); i++) {
                    JSONObject first = itemsArray.getJSONObject(i);
                    JSONObject volume = new JSONObject("volumeInfo");
                    String title = volume.getString("title");
                    JSONArray authorsArray = volume.getJSONArray("authors");
                    String author = authorsArray.getString(0);

                    Book b = new Book(title, author);
                    booklist.add(b);
                }

            } catch (JSONException e) {
                Log.e(LOG_TAG, "Problem parsing the book JSON results", e);
            }
            return booklist;
        }
    }

我的图书适配器:

    public class BookAdapter extends ArrayAdapter<Book> {
    public BookAdapter(Context c, ArrayList<Book> book) {
        super(c, 0, book);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        View list = convertView;
        if (list == null) {
            list = LayoutInflater.from(getContext()).inflate(R.layout.item, parent, false);

        }
        Book b = getItem(position);

        TextView titleTextView = (TextView) list.findViewById(R.id.title);
        titleTextView.setText(b.getName());

        TextView author = (TextView) list.findViewById(R.id.author);
        author.setText(b.getAuthor());


        return list;
    }
}

【问题讨论】:

  • 不要把你的整个代码放在你的问题中我建议你看看这个how to ask

标签: java android android-listview android-adapter


【解决方案1】:

您似乎错过了在活动中调用异步任务

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

 list = (ListView) findViewById(R.id.list);
new BookAsynck().execute(bookUrl);
}

【讨论】:

  • 我试过了,我得到了这个错误:java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
  • 在 oncreate 中再次删除 Listview 声明我编辑了我的代码
【解决方案2】:

欢迎来到stackoverflow!!

从 Android 9 开始,未加密的请求将不起作用,这意味着 HttpsURLConnection 将起作用,但 HttpURLConnection 将不起作用。

那么您尝试连接的 URL 必须具有 https:// 访问权限,或者您应该将其包含在您的清单中

android:usesCleartextTraffic="true"

【讨论】:

  • 还是什么都没发生
  • 如何在请求中进行这种加密
  • HttpsURLConnection 进行加密,但正如我所说的 URL 网站必须是安全网站,必须是 https:// 网站,而不是 http://,当然您的 URL 必须以 https 开头:// 在所有 catch() 中设置断点并查看异常消息
  • 我的错误在这里:books = Utils.fetchBookData(bookUrl); , insted of (bookUrl) , 我添加了 (string[0]), 它工作了, 谢谢你的询问
【解决方案3】:

onCreate()更改下面的行

ListView list = (ListView) findViewById(R.id.list);

list = (ListView) findViewById(R.id.list);

【讨论】:

  • 仍然没有显示
  • @linasaeed 您是否调试并检查在设置为 ListView 适配器之前是否获得项目列表?
  • 是的,我的错误在这里:books = Utils.fetchBookData(bookUrl); ,插入 bookUrl ,我添加了字符串 [0],它起作用了,感谢您的询问
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 1970-01-01
相关资源
最近更新 更多