Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.82
shulyakyarik
10 / 10 / 3
Регистрация: 28.03.2014
Сообщений: 156
#1

ProgressBar во время загрузки данных - Программирование Android

04.09.2014, 21:43. Просмотров 1500. Ответов 12
Метки нет (Все метки)

Есть activity с navigationdrawer-ом, который переставляет фрагменты. В центре фрагмента крутится прогресс бар, а позади него ListView с свойством visibility="gone". Я скачиваю данные и заполняю ими список, и в конце меняю видимость прогресс бара и списка.Только вот во время скачивания данных приложение как бы виснет, пока не получит данные, прогресс бар не крутится, action bar не меняется. Пробовал поместить загрузку данных в AsyncTask и в Runnable но зависание остается. С загрузкой из БД все быстро. Как сделать что бы прогресс бар крутился и данные загружались?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
05.09.2014, 11:30     ProgressBar во время загрузки данных #2
shulyakyarik, покажите как Вы поместили в AsyncTask.
shulyakyarik
10 / 10 / 3
Регистрация: 28.03.2014
Сообщений: 156
05.09.2014, 23:15  [ТС]     ProgressBar во время загрузки данных #3
YuraAAA, вот так с AsyncTask:
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class ToDoListFragment extends Fragment {
 
    ExpandableListView expandableListView;
    View v;
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.fragment_to_do_list, null);
        expandableListView = (ExpandableListView)v.findViewById(R.id.expandableListView);
 
        new AsyncTask<Void, Void, Void>() {
 
            ArrayList<JSONObject> arrayList;
            String parsed;
 
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
 
                try {
                    parsed = new GetToDos(getActivity()).execute().get();
                }
                catch (Exception e){
                    Toast.makeText(getActivity(), "Error", Toast.LENGTH_SHORT).show();
                }
 
 
            }
 
            @Override
            protected Void doInBackground(Void... params) {
                try{
                    arrayList = new ArrayList<JSONObject>();
                    JSONArray jsonArray = new JSONArray(parsed);
                    for (int i = 0; i < jsonArray.length(); i++)
                        arrayList.add(jsonArray.getJSONObject(i));
                }
                catch (Exception e){
                    Log.e("Error", "");
                }
 
                return null;
            }
 
            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);
 
                    expandableListView.addHeaderView(new View(getActivity()));
                    expandableListView.addFooterView(new View(getActivity()));
                    expandableListView.setAdapter(new ToDoAdapter(getActivity(), arrayList));
                    for(int i = 0; i < arrayList.size(); i++)
                        expandableListView.expandGroup(i);
                    expandableListView.setVisibility(View.VISIBLE);
                    (v.findViewById(R.id.progressBar)).setVisibility(View.GONE);
 
            }
        }.execute();
 
        return v;
    }
}
Способ с Runnable:
Java
1
2
3
4
5
6
new Thread(new Runnable() {
            @Override
            public void run() {
                // здесь код с методов что в AsyncTask выше
            }
}).run();
Spelcrawler
526 / 496 / 111
Регистрация: 12.03.2014
Сообщений: 1,648
Завершенные тесты: 1
05.09.2014, 23:52     ProgressBar во время загрузки данных #4
Цитата Сообщение от shulyakyarik Посмотреть сообщение
Java
1
2
3
4
5
expandableListView.addHeaderView(new View(getActivity()));
* * * * * * * * * * expandableListView.addFooterView(new View(getActivity()));
* * * * * * * * * * expandableListView.setAdapter(new ToDoAdapter(getActivity(), arrayList));
* * * * * * * * * * for(int i = 0; i < arrayList.size(); i++)
* * * * * * * * * * * * expandableListView.expandGroup(i);
Попробуйте в doInBackground перенести.
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
06.09.2014, 09:21     ProgressBar во время загрузки данных #5
Цитата Сообщение от shulyakyarik Посмотреть сообщение
try {
* * * * * * * * * * parsed = new GetToDos(getActivity()).execute().get();
* * * * * * * * }
* * * * * * * * catch (Exception e){
* * * * * * * * * * Toast.makeText(getActivity(), "Error", Toast.LENGTH_SHORT).show();
* * * * * * * * }
Это в doInBackground.
Цитата Сообщение от shulyakyarik Посмотреть сообщение
try{
* * * * * * * * * * arrayList = new ArrayList<JSONObject>();
* * * * * * * * * * JSONArray jsonArray = new JSONArray(parsed);
* * * * * * * * * * for (int i = 0; i < jsonArray.length(); i++)
* * * * * * * * * * * * arrayList.add(jsonArray.getJSONObject(i));
* * * * * * * * }
* * * * * * * * catch (Exception e){
* * * * * * * * * * Log.e("Error", "");
* * * * * * * * }
это в onPostExecute
shulyakyarik
10 / 10 / 3
Регистрация: 28.03.2014
Сообщений: 156
07.09.2014, 23:13  [ТС]     ProgressBar во время загрузки данных #6
YuraAAA, new GetToDos(getActivity()).execute().get(); - это же тоже AsyncTask. Если перенести это в doInBackground то ничего не работает(прогресс бар продолжает крутится, а список не появляется).
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
08.09.2014, 11:09     ProgressBar во время загрузки данных #7
shulyakyarik, это чья таска? Ваша? Или какая-то либа? Покажите её код, разберёмся
shulyakyarik
10 / 10 / 3
Регистрация: 28.03.2014
Сообщений: 156
08.09.2014, 16:26  [ТС]     ProgressBar во время загрузки данных #8
YuraAAA, этот AsyncTask скачивает и возвращает JSON строку. Написал его я
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,724
09.09.2014, 10:11     ProgressBar во время загрузки данных #9
shulyakyarik, по правилам AsyncTask, код в onPreExecute и в inPostExecute может обращаться к интерфейсу, а в doInBackground - нет. Посему, все "долгоиграющие" операции, связанные с вычислениями, обращениям в БД, URL, файлам и т.д. должны находиться в doInBackground, а всё остальное - в onPreExecute и onPostExecute. Кстати, эти 2 последних метода могут и вовсе отсутствовать. Поэтому обычно в onPreExecute и onPostExecute ставится режим видимости или невидимости ProgressBar, а также вывод всевозможных данных на экран. Если не ошибаюсь, значение имеют также результаты, возвращаемые функциями. У вас они ничего не возвращают (void), и возможно, поэтому ProgressBar не крутится.
Spelcrawler
526 / 496 / 111
Регистрация: 12.03.2014
Сообщений: 1,648
Завершенные тесты: 1
09.09.2014, 11:45     ProgressBar во время загрузки данных #10
CoolMind, не совсем верно, в doInBackground() можно обращаться к ui, но только если элементы к которым обращаешься не видно. Например есть LinearLayout с visibility = GONE, на него можно добавить сколь угодно элементов в doInBackground(), а в onPostExecute() сделать visibility = VISIBLE. Так же можно добавлять по элементу за раз (например при загрузке кучи картинок с интернета) методом publishProgress() этот метод будет передавать параметры в метод onProgressChanged()(точно не помню название, что-то похожее) и он(этот onProgressChanged()) может работать с ui потоком в штатном режиме.
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,724
19.09.2014, 11:30     ProgressBar во время загрузки данных #11
Spelcrawler, сегодня проверил. При попытке доступа к UI-элементам, хоть INVISIBLE, хоть GONE - вылет с ошибкой "Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views".
Так что доступ к UI-элементам - только в onPreExecute и onPostExecute.
Spelcrawler
526 / 496 / 111
Регистрация: 12.03.2014
Сообщений: 1,648
Завершенные тесты: 1
19.09.2014, 11:43     ProgressBar во время загрузки данных #12
CoolMind, странно это. У меня работало, но я добавлял элементы в AlertDialog до его отображения. Т.е. в принципе того куда я это добавлял вообще не было). И еще у меня в одном AsynkTaske срабатывал Toast, а в другом - нет. Возможно зависит от контекста.

Добавлено через 6 минут
А, понял в чем дело: я создавал этот диалог прямо в doInBackround, то есть
Цитата Сообщение от CoolMind Посмотреть сообщение
Only the original thread that created a view hierarchy can touch its views
Уже не будет т.к. создал я его там и меняю там же. А вот как я его потом показывал не помню)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.09.2014, 10:04     ProgressBar во время загрузки данных
Еще ссылки по теме:
Остановка ProgressBar Android
Android Параллелизация работы с ProgressBar-ом
Про Handler и ProgressBar Android
ProgressBar в виде фигуры человечка Android
Android Не получается вывести progressbar в SupportActionBar

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

Или воспользуйтесь поиском по форуму:
CoolMind
418 / 401 / 65
Регистрация: 06.10.2012
Сообщений: 1,724
26.09.2014, 10:04     ProgressBar во время загрузки данных #13
Spelcrawler, вообще, это всё интересно, конечно. Я недавно ваш метод решил применить при асинхронной загрузке Яндекс-карт. Создал их в doInBackground, тут же скрыл, потом сделал необходимые действия, а в onPostExecute отобразил и доделал некоторые вещи типа отображения кнопок приближения. Не скажу, что быстрее получилось (хотя, может быть), но зато действительно, можно получить доступ к UI-элементам, созданным в doInBackground. Яндекс-карты я потом выбросил, потому что они почему-то всё равно не грузятся на Android 4.4.2, а причину поймать так и не смог.

Добавлено через 12 минут
Не знаю, правильно ли рассуждаю, но в некоторых случаях даже обращение к getActivity() в doInBackground может привести к ошибке. Некоторые классы и компоненты требуют доступа к контексту, ну и изредка я писал напрямую, допустим, new Preferences(getActivity()). Что иногда приводило к ошибке. Теперь везде заменяю на context (типа Context), а в методе onCreateView пишу: "context = getActivity();".
Yandex
Объявления
26.09.2014, 10:04     ProgressBar во время загрузки данных
Ответ Создать тему
Опции темы

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