Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.70/10: Рейтинг темы: голосов - 10, средняя оценка - 4.70
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
1

AsyncTask тормозит

17.02.2016, 12:50. Просмотров 1782. Ответов 25
Метки нет (Все метки)

Подскажите пожалуйста, делалю загрузку данных с сервера через asyncTask и возвращаются результат, а дальше делаю обработку этих данных во фрагменте, в приложении всего три таба, загрузка данных происходит в последнем табе, так вот, если нажимаешь на табу где происходит запрос к asyncTask приложение немного притормаживает пока эти данные не загрузятся.
После возврата данных в формате json они циклом помещаются в массив и выводятся через spinner на экран.
По какой причине может происходить подлагивание приложения?

Добавлено через 24 минуты
Прочитал про хендлер появилось подозрение что томозит потому что цикл это для андроид тяжёлый код и его тоже нужно поместить в отдельный поток, я правильно понимаю?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.02.2016, 12:50
Ответы с готовыми решениями:

AsyncTask
Привет. Знаю, что в AsyncTask doInBackground() обращатся к компонентам UI нельзя. Когда я пытаюсь...

AsyncTask
Использую AsyncTasc class MyT extends AsyncTask<Void, Void, Void> { @Override...

AsyncTask и get()
Создаю асинхронный процесс, где в onPreExecute() запускаю анимированный ProgressDialog. После...

AsyncTask
Здравствуйте, при использовании двух одинаковых методов получается разный результат. AsyncTask в...

Отмена AsyncTask
Привет. Есть такой код: @Override protected Void doInBackground(Void... params) { try {...

25
YuraAAA
1578 / 1319 / 282
Регистрация: 25.10.2009
Сообщений: 3,436
Записей в блоге: 2
17.02.2016, 13:05 2
Westbam381, покажите Вашу asynctask
0
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
17.02.2016, 13:56  [ТС] 3
YuraAAA,
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class AsyncTaskc extends AsyncTask<Void, String, String> {
 
    private String urls;
 
    public AsyncTaskc(String url) {
        urls = url;
    }
 
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
    }
 
    @Override
    protected String doInBackground(Void... voids) {
        BufferedReader reader = null;
        StringBuilder buf = new StringBuilder();
        try {
            URL url = new URL(urls);
            HttpURLConnection c = (HttpURLConnection)url.openConnection();
            c.connect();
            reader = new BufferedReader(new InputStreamReader(c.getInputStream()));
            String line=null;
            line = reader.readLine();
            c.disconnect();
            buf.append(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buf.toString();
    }
 
    @Override
    protected void onCancelled() {
        super.onCancelled();
    }
Добавлено через 33 минуты
YuraAAA,
Я понял почему мой поток блокирует, так как чтоб получить результат я вызывают метод get, а он пока ждёт блокирует мой UI пока не получит результат.
Правильно?
0
Pablito
2836 / 2254 / 762
Регистрация: 12.05.2014
Сообщений: 7,892
Завершенные тесты: 1
17.02.2016, 13:59 4
этот таск вообще что-то и куда-то возвращает или я невнимательно смотрю?
0
17.02.2016, 13:59
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
17.02.2016, 14:54  [ТС] 5
Паблито,
Наверное)
Я написал что я методом get во фрагменте получаю результат который приходит с сервера
Java
1
return buf.toString();
И уже там циклом заполняю массив данными и вывожу в spinner
Я думаю что тормоза из-за того что метод get блокирует мой ui, я прав?
0
Pablito
2836 / 2254 / 762
Регистрация: 12.05.2014
Сообщений: 7,892
Завершенные тесты: 1
17.02.2016, 15:15 6
да, я видел насчет get
но это извращение, по-хорошему надо любым способом передавать в асинктаст ссылку на активити или фрагмент и когда таск отработает - возвращать результат из метода onPostExecute
0
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
17.02.2016, 15:26  [ТС] 7
Паблито,
Можно пример
А что если у меня этот результат каждый раз разный, я не думаю что для всех задач нужно делать отдельный asyncTask?
Просто до этого писал на php и привык что у меня есть определённый класс который отвечает за одну задачу и который должен что-то вернуть, а уже с результатом я делаю что мне нужно.
Так как в данном случае asyncTask может вернуть массим json или объект или строку а может число, как быть в такой ситуации?
0
Pablito
2836 / 2254 / 762
Регистрация: 12.05.2014
Сообщений: 7,892
Завершенные тесты: 1
17.02.2016, 16:14 8
если на сервере вменяемое API то асинктаск можно написать так, что ему на вход подается url, а он будет
получать json и парсить его сразу в объект, например MyCoolResponse response;

потом этот объект возвращается в активити и там уже принимается решение что с ним делать
а когда задача стоит так - у меня там х.з. что может вернуться из асинктаска, то далеко так не уехать

и тут бесполезно спрашивать готовый код как тут любят делать, рано еще просить готовый код
0
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
17.02.2016, 16:39  [ТС] 9
Паблито,
Мне готовый код не нужен, мне нужен совет знающего человека чтоб он сказал как правильно сделать так как java я только начинаю учить, а так как это строготипизированый язык не то что php у меня возникают некоторые сложности с освоением.
И если я прошу помощи это не значит что писать нужно за меня, это значит что нужно подсказать как это правильно сделать и может быть показать пример или дать ссылку так как я думаю я не первый кто задаёт такой вопрос, и последние я могу просто не знать как спросить у гугла то что мне нужно.
А не помогать людям которые просят помощи это жлобство и я не понимаю для чего тогда делать форум если все ответы сводятся к тому что или нет ответа или он типо такого содержание "ты что гуглом пользоваться не умеешь?" тогда у меня встречный вопрос, зачем этот форум?
Я когда учил php у меня было не меньше вопросов но с их решением было немного проще взять хотя бы док. Он на русском языке, кто-то может сказать так выучи, так может мне тогда изучить что такое электричество если мне нужно всего лишь провод поменять?
Я не хочу никого обидить, ну раз уж вы сидите на этом форуме и знаний у вас больше чем у другого, помогите ему, земля ведь круглая!
0
Pablito
2836 / 2254 / 762
Регистрация: 12.05.2014
Сообщений: 7,892
Завершенные тесты: 1
17.02.2016, 16:59 10
Цитата Сообщение от Westbam381 Посмотреть сообщение
земля ведь круглая
пфф, она - геоид, ну ладно

пример таска
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MyTask extends AsyncTask<String, Void, String> {
    private final OnTaskComplete callback;
 
    public MyTask(OnTaskComplete callback) {
        this.callback = callback;
    }
 
    @Override
    protected String doInBackground(String... urls) {
        String url = urls[0]; // берем урл и подключаемся куда-то там и что-то получаем
        String str = "json avada kedavra"; // типа получили json
        return str; // передаем в onPostExecute
    }
 
    @Override
    protected void onPostExecute(String s) {
        callback.onTaskComplete(s); // передаем результат назад объекту, который реализовал интерфейс OnTaskComplete, он чуть ниже написан
    }
 
    interface OnTaskComplete {
        void onTaskComplete(String json);
    }
}
и где-то во фрагменте или активити, откуда этот таск будет стартовать, сначала реализовываем интерфейс нашего таска, я тренировался на фрагменте, поэтому так
Java
1
public class Fragment1 extends Fragment implements MyTask.OnTaskComplete
и ide попросит добавить метод
Java
1
2
3
4
    @Override
    public void onTaskComplete(String json) {
        // делаем что-то с полученой из асинктаска строкой
    }
ну и как этот таск запускать
Java
1
new MyTask(this).execute("url");
он отработает и только когда он отработает - вызовется метод onTaskComplete
в примере возвращается String
но я выше писал, что лучше что бы в таске json парсился в объект, и в cakkback возвращается готовенький POJO класс, а не строка над которой потом еще надо попотеть
1
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
17.02.2016, 17:21  [ТС] 11
Паблито, Спасибо, не сложно ведь, правда?)
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    @Override
    protected String doInBackground(Void... voids) {
        BufferedReader reader = null;
        StringBuilder buf = new StringBuilder();
        try {
            URL url = new URL(urls);
            HttpURLConnection c = (HttpURLConnection)url.openConnection();
            c.connect();
            reader = new BufferedReader(new InputStreamReader(c.getInputStream()));
            String line=null;
            line = reader.readLine();
            c.disconnect();
            buf.append(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buf.toString();
    }
Это код вообще правильный для получения данных?
0
Pablito
2836 / 2254 / 762
Регистрация: 12.05.2014
Сообщений: 7,892
Завершенные тесты: 1
17.02.2016, 17:34 12
Цитата Сообщение от Westbam381 Посмотреть сообщение
Это код вообще правильный для получения данных?
то есть с той проблемой уже все, разобрались, все ясно как божий день и понятно что куда вставлять?
0
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
17.02.2016, 18:59  [ТС] 13
Паблито,
В теории да, на практике ещё не пообовал, пока нет ПК рядом, а так мне нужно добавить ещё интерфейс в asyncTask который будет возвращать мне мои данные, в фрагменте сделать наследование от мего asyncTask класса там где я делаю вызов передать ещё параметр this, я так понимаю это и есть та самая ссылка о которой вы писали выше, в asyncTask нужно ещё добавит в конструктор callback правда мне не понятно пока что это, и в фрагменте дописать ещё один метод куда будут возвращается мои данные только после того как они будут получины. Я все правильно понял?
0
Pablito
2836 / 2254 / 762
Регистрация: 12.05.2014
Сообщений: 7,892
Завершенные тесты: 1
17.02.2016, 19:25 14
Цитата Сообщение от Westbam381 Посмотреть сообщение
в фрагменте сделать наследование от мего asyncTask класса
категорически нет

1. есть фрагмент и есть отдельный класс - наследник асинктаска
2. в асинктаске (в принципе можно и отдельно, но так компактнее) объявляем интерфейс
3. когда мы создаем асинктаск - в конструктор подаем некий объект, этот объект должен уметь получить результат от асикнтаска. Как? Он должен реализовать метод интерфейсаиз асинктаска.
В примере этот объекст - фрагмент. И если таск стартуем из фрагмента то и передаем this.

Короче интерфейс нужен что бы асинктаск мог вернуть результат. Вопрос - куда вернуть, кому?
Вот "кому вернуть результат" и есть переменная callback, ну такое название, назови ее kuda_perezvonit, если так будет понятнее.

Добавлено через 17 минут
Цитата Сообщение от Westbam381 Посмотреть сообщение
Это код вообще правильный для получения данных?
лично меня напрягает каждый раз писать эти циклы к собирать строки, поэтому я пользуюсь такой библиотекой
вот примерно так выглядел бы код doInBackground()
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
    @Override
    protected String doInBackground(String... urls) {
        String str = null;
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(urls[0]).build();
        try {
            Response response = client.newCall(request).execute();
            str = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
библиотека подключается в build.gradle
XML
1
compile 'com.squareup.okhttp3:okhttp:3.0.0-RC1'
0
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
18.02.2016, 18:46  [ТС] 15
Паблито,
Получилось сделать на твоём премере, но для этого мне пришлось сделать три отдельных класса асинктаск для каждого спиннера и для таблици, теперь все работает ничего не тормозит да и во фрагменте стало почище.
0
REALIST07
Автор FAQ
Автор FAQ
195 / 194 / 21
Регистрация: 11.06.2010
Сообщений: 1,018
18.02.2016, 19:02 16
Необязательно делать 3, это по-нубски, можно сделать 1 универсальный:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class ExecutorCommOnServer
        extends AsyncTask<Void, Void, PostExecuteData>
{
 
    private final int method;
    private final IOnPostExecutable i;
    private PostExecuteData data;
 
    public ExecutorCommOnServer(int method, IOnPostExecutable i) {
        this.method = method;
        this.i = i;
      
        data = new PostExecuteData(method);
    }
 
    @Override
    protected PostExecuteData doInBackground(Void... params)  {
 
     
        try {
            
 
            switch (method) {
                case Helper.METHOD_FIND:  break;
                
                case Helper.METHOD_REGISTER : break;
 
                case Helper.METHOD_REGISTER_BUSINESS: break;
                
                case Helper.METHOD_DELETE_ACCOUNT:  break;
                
          return new PostExecuteData(...);
 
    }
 
    @Override
    protected void onPostExecute(PostExecuteData postExecuteData) {
        super.onPostExecute(postExecuteData);
 
        if (i != null)
            i.onPostExecute(postExecuteData);
    }
Где IOnPostExecutable - интерфейс, принимающий в параметр любой ваш класс с данными
PostExecuteData - пример моего класса с данными
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class PostExecuteData {
    private int method;
    private String result;
 
    public PostExecuteData(int method, String result ){
        this.method = method;
        this.result = result;
    }
    public PostExecuteData(int method ){
        this.method = method;
 
    }
 
    public void setMethod(int method) {
        this.method = method;
    }
    public int getMethod() {
        return method;
    }
 
    public String getResult() {
        return result;
    }
 
    public void setResult(String result) {
        this.result=result;
    }
 
 
    @Override
    public String toString() {
        return "PostExecuteData{" +
                "method=" + method +
                ", result='" + result +'}';
    }
}
0
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
18.02.2016, 22:33  [ТС] 17
REALIST07,
Да я знаю что копия кода это плохо, но из за того что у меня мало знаний по java я не знаю что куда приходит и уходит или что конкретно нужно передать, как бы я не совсем не соображаю кое что понятно так как программирование учил.
Например взять this в php это означает этот объект, тут я не могу понять так как иногда при передачи this в
качестве параметра он может подсвечивается как не правильный параметр, ещё мне не понятно пока с областью видимости в php например если переменная созданная приват (например) её видно во всем классе и без разници в каком методе, а тут совсем по другому, переменную не видно например в обработчика выбора spinner и т.д.

Добавлено через 1 минуту
В общем нужно пройти азы по java)
0
YuraAAA
1578 / 1319 / 282
Регистрация: 25.10.2009
Сообщений: 3,436
Записей в блоге: 2
19.02.2016, 00:42 18
Цитата Сообщение от Westbam381 Посмотреть сообщение
В общем нужно пройти азы по java)
Гениально!)
0
Westbam381
2 / 2 / 0
Регистрация: 07.01.2015
Сообщений: 26
19.02.2016, 06:36  [ТС] 19
REALIST07,
Ещё раз пересмотрел код, и вроде как тучи начинают рассеиваться)
Только есть пару вопросов
data = new PostExecuteData(method);
Для чего data если она не используется?

switch (method) {
case Helper.METHOD_FIND: break;

case Helper.METHOD_REGISTER : break;

case Helper.METHOD_REGISTER_BUSINESS: break;

case Helper.METHOD_DELETE_ACCOUNT: break;
Что это такое и для чего?
return new PostExecuteData(...);
Что значит точки?

Ну а так в принципе все ясно) создаётся один асинктаск что-то делает, а результат возвращает вот этому классу PostExecuteData в этом классе есть метод который возвращает результат асинктаск.
Правильно?
0
REALIST07
Автор FAQ
Автор FAQ
195 / 194 / 21
Регистрация: 11.06.2010
Сообщений: 1,018
19.02.2016, 20:34 20
Да, это я выдрал из своего кода, свои задачи передавайте как int method = 0,1,2 и в кейсе делайте, что вам нужно и возвращайте результат
0
19.02.2016, 20:34
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2016, 20:34

AsyncTask+CheckBox
Здравствуйте, интересует вопрос нужно в функцию AsyncTask послать несколько строк, в зависимости...

Exception в AsyncTask
Доброго всем. Проблема вот в чем: периодически во время выполнения одного из потоков в AsyncTask...

AsyncTask ObjectAnimator
Добрый вечер. Прошу помочь мне. Пытаюсь написать карточную игру. В игре игрок выбирает две карты,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru