Получить данные со страницы для последующего использования

291
25 марта 2022, 01:20

друзья. Для работы моей программы требуется:

  1. Получить данные со страницы сайта по протоколу https (данные доступа к БД)
  2. Используя эти данные подключиться к БД и получить информацию о товарах интернет-магазина

Я написал код получения данных подключения к БД (п.1)

        String key = "***токен***";
        String host = "https://rosfixator.ru/";
        String page = "android-mysql.html";
        URL url = null;
        HttpsURLConnection connection = null;
        InputStreamReader streamReader = null;
        StringBuffer  myData = null;
        try {
            url = new URL(host + page + "?key=" + key);
            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
            myData = print_content(con);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
private StringBuffer print_content(HttpsURLConnection con){
        StringBuffer myData = new StringBuffer();
        if(con!=null){
            try {
                    BufferedReader br =
                        new BufferedReader(
                                new InputStreamReader(con.getInputStream()));
                String input;
                    while ((input = br.readLine()) != null){
                    myData.append(input);
                    }
                br.close();
                } catch (IOException e) {
                e.printStackTrace();
            }
            }
        return myData;
    }

При попытке выполнения программы выбрасывает исключение что-то вроде "Не могу запустить в главном потоке". Вижу выход запуска в асинхронном режиме. Создал отдельный класс, расширяющем AsyncTask и код разместил в doInBackground. Но поскольку программа запускается в асинхронном режиме, как я могу быть уверен в том, что к моменту вызова подключения к БД с использованием данных из myData, они будут доступны. Добавление костыля в виде задержки

TimeUnit.SECONDS.sleep(5);

но мне кажется это не правильно. Ведь сервер может и не ответить за 5 секунд, а значит приложение развалится.

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

Answer 1

Все сетевые подключения в андроиде должны выполняться в фоне. Самый простой способ для этого - использовать AsyncTask. Например здесь отлично всё расписано об этом классе и как его использовать, с подробными примерами.

Вот пример реализации:

class AsyncConnect extends AsyncTask<Void, Void, StringBuffer> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Вызывается перед doInBackground и тут есть доступ к UI
    }
    @Override
    protected StringBuffer doInBackground(Void... voids) {
        // Тут уже выполняем всю работу по подключению к сайту и т.п.
        // Доступа к UI здесь уже нет! (т.е. например вставить что-то в textView здесь нельзя)
        String key = "***токен***";
        String host = "https://rosfixator.ru/";
        String page = "android-mysql.html";
        URL url = null;
        HttpsURLConnection connection = null;
        InputStreamReader streamReader = null;
        StringBuffer  myData = null;
        try {
            url = new URL(host + page + "?key=" + key);
            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
            myData = print_content(con);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return myData;
    }
    private StringBuffer print_content(HttpsURLConnection con){
        StringBuffer myData = new StringBuffer();
        if(con!=null){
            try {
                BufferedReader br =
                        new BufferedReader(
                                new InputStreamReader(con.getInputStream()));
                String input;
                while ((input = br.readLine()) != null){
                    myData.append(input);
                }
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return myData;
    }
    @Override
    protected void onPostExecute(StringBuffer result) {
        super.onPostExecute(result);
        // Работа doInBackground завершена и тут мы можем вывести результат в интерфейс.
        // Доступ к UI есть!
    }
}
READ ALSO
MySQL из сайта на Android - возможно ли это?

MySQL из сайта на Android - возможно ли это?

Могу ли я в своём Android-приложении брать данные из БД MySQl, расположенной на сервере?

193
Adapter не распознает setter

Adapter не распознает setter

У менять есть класс Н, созданный для адаптераВ классе М(адаптер) я вызываю сеттер из класса Н, но его не распознает, подчеркивает краснsv

93
Нужно написать собственную реализацию ArrayList , проблема с sublist

Нужно написать собственную реализацию ArrayList , проблема с sublist

Столкнулся вот с такой проблемой: Есть задание: - нужно написать собственную реализацию ArrayListОсновная проблема заключается в том что не могу...

71
После установки Bground пропала кнопка

После установки Bground пропала кнопка

Пропала кнопка после установки BgroundЛэйблы пропали тоже (При загрузке картинки из проекта src\UI\Bground

134