AsyncTask выполняет Serial вместо Parallel (HTTPost TimeOutException)

EDIT: AsyncTask was called lots of times to update status in Server and at the same time, my app tried to upload files. AsyncTask by default, do only one operation at a time (serial mode) but you can put it in Parallel mode, as I answered below.

После нормальной работы в течение нескольких часов (а иногда и нескольких минут) мое приложение перестает подключаться к серверу с помощью HTTPost. Я установил тайм-аут на 20 секунд, и сейчас хорошее время, так как соединение хорошее (Wi-Fi). Я протестировал его на двух серверах: на моем собственном компьютере и на виртуальном частном сервере. Проблема бывает одинаково.

Есть ли способ или причина для того, чтобы Android не подключался к http-серверу? Есть ли еще одна причина для этого? Есть ли лучший способ сделать это?

Спасибо!!

Вот как я делаю запрос POST:

try{
        new ConexaoHTTPPost.SolicitaDados(parametros).execute(url).get(20000, TimeUnit.MILLISECONDS);
     } catch (InterruptedException e) {
                            new ReportException(getApplicationContext()).send(e,classeToErr);
                        } catch (ExecutionException e) {
                            new ReportException(getApplicationContext()).send(e,classeToErr);
                        } catch (TimeoutException e) {
                            new ReportException(getApplicationContext()).send(e,classeToErr);
                        }

Код HTTPost:

public class ConexaoHTTPPost {
    public static String postDados(String urlUsuario, String parametrosUsuario) {
        URL url;
        HttpURLConnection connection = null;

        try {
            url = new URL(urlUsuario);
            connection = (HttpURLConnection) url.openConnection();

            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Content-Lenght","" + Integer.toString(parametrosUsuario.getBytes().length));
            connection.setRequestProperty("Content-Language","pt-BR");
            connection.setUseCaches(false); 
            connection.setDoInput(true);
            connection.setDoOutput(true);

            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
            outputStreamWriter.write(parametrosUsuario);
            outputStreamWriter.flush();
            outputStreamWriter.close();

            InputStream inputStream = connection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));

            StringBuffer resposta = new StringBuffer();

            String linha;
            while ( (linha = bufferedReader.readLine()) != null){
                resposta.append(linha);
                resposta.append('\r');
            }

            bufferedReader.close();

            return resposta.toString();
        }catch (Exception erro){
            return null;
        }finally {
            if (connection != null){
                connection.disconnect();
            }
        }
    }

    public static class SolicitaDados extends AsyncTask<String, Void, String> {

        private String parametros;
        //private String resultado = null;

        public SolicitaDados(String parametros) {
            this.parametros = parametros;
        }

        @Override
        protected String doInBackground(String... urls) {
            return ConexaoHTTPPost.postDados(urls[0], parametros);
        }
        /*
        @Override
        protected void onPostExecute(String resultado){
            this.resultado = resultado;
        }
        */
    }
}

После того, как эта ошибка произошла, я пропинговал сервер, и все в порядке

Israel Agostinho 10.03.2018 09:37
new ConexaoHTTPPost.SolicitaDados(parametros).execute(url).get( ?? Вы запускаете AsyncTask, а затем вызываете на нем .get()?
greenapps 10.03.2018 13:04

Вот как я нашел TimeOut. Я еще новичок в программировании.

Israel Agostinho 12.03.2018 05:58

Почему это установило тайм-аут? Бред какой то! Вам следует обойтись без .get (), если это действительно асинхронная задача. (Почему вы не подтвердили?). Измените логику работы без .get ().

greenapps 12.03.2018 11:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
39
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я решил Это. Я использовал метод выполнять(), но на самом деле правильный способ - использовать выполнитьOnExecutor () в этой строке:

new ConexaoHTTPPost.SolicitaDados(parametros).execute(url).get(20000, TimeUnit.MILLISECONDS);

выполнять() выполняет все последовательно в потоке пользовательского интерфейса, поэтому вы не можете загружать два файла (или данных) одновременно, потому что соединение блокируется потоком пользовательского интерфейса.

При использовании метода executeOnExecutor () вы можете загрузить несколько файлов или данных. Мне нужно было только изменить эту строку, как показано:

new ConexaoHTTPPost.SolicitaDados(parametros).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url).get(20000, TimeUnit.MILLISECONDS);

Я его поменял везде, где он есть. PS: Вы должны использовать AsyncTask.THREAD_POOL_EXECUTOR в качестве исполнителя потока.

Другие вопросы по теме