почему ListView не заполняется, когда я использую AsyncTask? - PullRequest
0 голосов
/ 28 сентября 2019

Я пишу приложение, использующее API поиска книг Google. Предполагается, что приложение должно отображать список книг на основе поискового запроса, который я предоставляю в коде приложения в виде строки. Я использую внутренний класс AsyncTask.Для выполнения фоновой работы (выполнение HTTP-запроса, JSON-форматирование и т. д.) у меня также есть адаптер костюма книги и класс книги для получения данных, моя проблема в том, что приложение не отображает ни одной книги в виде списка.

вот мой код:

открытый класс MainActivity расширяет 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);
    }
}

}


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

// если запрос был успешным (код 200) // получаем входной поток и декодируем его

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

// декодируем входной поток в строку, содержащую ответ J с сервера

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

}

Ответы [ 3 ]

0 голосов
/ 28 сентября 2019

Добро пожаловать в stackoverflow !!

Начиная с Android 9, запросы без шифрования не будут работать, это означает, что HttpsURLConnection будет работать, но HttpURLConnection не будет.

Тогда URL, который вы пытаетесь подключить, должен иметь доступ https: //, или вы должны включить его в манифест

android:usesCleartextTraffic="true"
0 голосов
/ 30 сентября 2019

Измените следующую строку с onCreate()

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

на

list = (ListView) findViewById(R.id.list);
0 голосов
/ 28 сентября 2019

Похоже, вы пропустили вызов своей асинктической задачи во время активности

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

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