Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
1

Handler при пересоздании активити

07.07.2016, 16:06. Просмотров 574. Ответов 25
Метки нет (Все метки)

У меня есть поток Thread, который запускается во фрагменте и получает ссылку на изображение с сервера(парсит JSON выделяет ссылку). И Handler который связан с UI потоком, запускает Runnable в UI потоке, в котором через Glide загружает изображение в Layout. Вопрос в следующем: фрагмент может пересоздаваться не только при поворотах, а и при смене языка и доступности клавиатуры и др ситуации. И в итоге после этого пересоздания с Handlerом начнутся проблемы. Что нужно делать с Handlerом при пересоздании активити? Как учесть этот момент? Может в onDestroy() как то можно его отменять можете рассказать решение??
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.07.2016, 16:06
Ответы с готовыми решениями:

Сохранение данных при пересоздании активити
Добрый день, может кто-то сталкивался: имеются данные, которые я хочу добавить...

Сохранить состояние презентера при пересоздании (повороте) активити
Вот у презентера можно реализовать метод onDetach() в котором он обнуляет...

Работа с Handler из другого активити
Здравствуйте, пишу чат приложение и не могу понять как можно обрабатывать...

Утечка памяти при использовании Handler
Добрый день, многоуважаемые форумчане :). Прошу помощи в решении проблемы. ...

На телефоне highscreen 3 на всех активити происходит быстрый самовозврат к главной активити
Сделал меню в виде ListView. При клике на меню запускаются активити. На...

25
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
08.07.2016, 08:46 2
yura91, handler имеет ссылку на activity и поэтому она не может быть удалена даже при пересоздании - новая создастся, но и старая будет хоть и в мусорке, но недобитая. Я убиваю handler в onpause и пересоздаю в onresume
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
08.07.2016, 14:04  [ТС] 3
То есть в onPause
Java
1
2
3
4
5
6
if (sThread.isAlive()){
 
sThread.setHandler(null);
 
 
}
а в onresume
Java
1
2
3
4
if (sThread.isAlive()){
sThread.setHandler(mHandler);
 
}
Так это делается да?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
08.07.2016, 14:43 4
yura91, у меня другой handler. у меня просто
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    private Handler handler;
 
    @Override
    protected void onResume () {
        super.onResume();
 
        handler = new Handler() { ... };
        handler.sendEmptyMessage(0);
    }
 
    @Override
    protected void onPause () {
        super.onPause();
 
        handler.removeMessages(0);
    }
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
08.07.2016, 14:56  [ТС] 5
Но дело в том что Handler может запускать кусок кода Runnable в UI потоке. А handler.sendEmptyMessage(0); и handler.removeMessages(0); это же только для случая когда он просто отправляет сообщения в UI поток или если Runnable то тоже это работает?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
08.07.2016, 15:00 6
yura91, к сожалению не в курсе как вы одно с другим переплели. handler может то что может. у меня работа с ним организована как показано. ассоциацию handler с потоком я не за свою жизнь еще делал(
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
08.07.2016, 16:15  [ТС] 7
А вот такая конструкция
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
Thread t = new Thread(new Runnable() {
                        public void run() {
 
                            OpenWeather weather = new OpenWeather();
 
                            weather.sendQuery(query);
 
                            h.sendEmptyMessage(1);
                            // пишем лог
 
 
                        }
                    });
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
 @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editTextCityName = (EditText)findViewById(R.id.cityname);
 
        h = new Handler(){
            public void handleMessage(android.os.Message msg) {
 
          //Выполняем действия
            };
        };
Просто почему handler.sendEmptyMessage(0); у вас внутри Handlerа этот метод должен же вызываться внутри потока. Он же оттуда отправляет сообщение разве нет?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
08.07.2016, 16:33 8
yura91, сообщение может быть отправлено оттуда откуда виден объект. У меня первое сообщение посылается либо при возобновлении либо при неком событии. После этого handler шлёт сообщения сам себе с задержкой пока не отработает поток за которым он следит или его (часового) не снимут с дежурства при паузе
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
08.07.2016, 17:38  [ТС] 9
Ну суть в том что в onPause нужно вызвать handler.removeMessages или removeCallbacks(если Runnable отправляем), чтобы все было удалено из очереди перед пересозданием активити так ведь, в этом суть?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
08.07.2016, 18:20 10
yura91, суть в том чтобы удалить сообщения из очереди - нет сообщений = нет ссылок на активити и она сможет спокойно умереть если что

Добавлено через 3 минуты
Кроме того если этого не делать хандлер обратится к мертвой активити если её пересоздало
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
09.07.2016, 11:10  [ТС] 11
У меня еще такой вопрос. Вот у меня идет как: создается активити в методе onCreate() я создаю поток, в потоке делаю сетевой запрос, получаю JSON, выделяю ссылку на картинку. Handler у меня создается внутри onCreate(), я запускаю его Runnable из потока и в нем загружаю в фон активити эту картинку через Glide. Также есть кнопка по ее нажатию пользователь может загрузить другую картинку в фон, но когда идет пересоздание активити то в фон загружается опять самая первая картинка. А как можно переделать код чтобы загружалась при пересоздании не самая первая картинка, а картинка которую пользователь загрузил после нажатия кнопки? Как грамотно построить приложение?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
09.07.2016, 11:16 12
yura91, очевидно надо где-то хранить текущую картину. Может в статике приложения или даже на диске если нет желания грузить её при запуске
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
09.07.2016, 12:36  [ТС] 13
а в статике как ее можно хранить? Просто статическую переменную создать которая содержит ссылку на картину да? и в Glide эту сохраненную ссылку просто передавать, можно так?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
09.07.2016, 12:40 14
yura91, в статике именно приложения а не Активити можно хранить битмап к примеру и присваивать его в oncreate элементу ui
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
09.07.2016, 13:07  [ТС] 15
А можно фрагмент кода небольшой на счет Bitmap? И еще в Android Studio есть горячая клавиша для автоформатирования кода. Так вот если делать это автоформатирование, то код форматируется в соответствии со стандартами кода Google верно?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
09.07.2016, 13:20 16
yura91, я в ADT сижу он сам все форматирует без кнопок фрагмент сейчас не могу кинуть позже
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
09.07.2016, 14:04  [ТС] 17
И еще такой вопрос смотри у меня приложение делает запрос на Opeweathermap и парсит JSON, загружает картинку в фон. И когда я начинаю сильно вертеть экран(делаю частые повороты в процессе загрузки изображения), то приложение падает с
07-09 13:52:59.008 13353-13703/com.uifragmentsexample.user.myuifragments W/System.err: org.json.JSONException: No value for 3h
07-09 13:52:59.008 13353-13703/com.uifragmentsexample.user.myuifragments W/System.err: at org.json.JSONObject.get(JSONObject.java:354)
07-09 13:52:59.008 13353-13703/com.uifragmentsexample.user.myuifragments W/System.err: at org.json.JSONObject.getString(JSONObject.java:510)
07-09 13:52:59.008 13353-13703/com.uifragmentsexample.user.myuifragments W/System.err: at com.uifragmentsexample.user.myuifragments.OpenWeather.jsonHelperGetString(OpenWeather.java:223)
07-09 13:52:59.008 13353-13703/com.uifragmentsexample.user.myuifragments W/System.err: at com.uifragmentsexample.user.myuifragments.OpenWeather.ParseJSONForecast(OpenWeather.java:116)
07-09 13:52:59.009 13353-13703/com.uifragmentsexample.user.myuifragments W/System.err: at com.uifragmentsexample.user.myuifragments.MainActivity$4$1.run(MainActivity.java:337)
07-09 13:52:59.009 13353-13703/com.uifragmentsexample.user.myuifragments W/System.err: at java.lang.Thread.run(Thread.java:838)
вот такой ошибкой. Как можно исправить эту проблему? Есть какая нибудь защита от этого?

Добавлено через 5 минут
Java
1
2
3
4
5
6
7
8
9
private String jsonHelperGetString(JSONObject obj, String k) {
        String v = null;
        if (obj != null) {
            try {
                v = obj.getString(k);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
Вот метод парсинга строки

Добавлено через 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
String ParseJSONForecast(String json) {
        String jsonResult = "";
        try {
            JSONObject JsonObject = new JSONObject(json);
            JSONObject city = jsonHelperGetJSONObject(JsonObject, "city");
            if (city != null) {
 
                String cod = jsonHelperGetString(JsonObject, "cod");
                Log.d("Func", cod);
                if (cod != null) {
                    if (cod.equals("200")) {
 
 
                        jsonResult += jsonHelperGetString(city, "name") + "\n";
                        jsonResult += jsonHelperGetString(city, "country") + "\n";
                        JSONObject coord = jsonHelperGetJSONObject(city, "coord");
                        if (coord != null) {
                            String lon = jsonHelperGetString(coord, "lon");
                            String lat = jsonHelperGetString(coord, "lat");
                            jsonResult += "lon: " + lon + "\n";
                            jsonResult += "lat: " + lat + "\n";
 
                        }
                        jsonResult += "\n";
                        Log.d("Func", jsonResult);
 
                        JSONArray list = jsonHelperGetJSONArray(JsonObject, "list");
 
                        if (list != null) {
                            Log.d("Func", "Here" + list.length());
                            for (int i = 0; i < list.length(); i++) {
                                JSONObject thisWeather = list.getJSONObject(i);
                                JSONObject main = jsonHelperGetJSONObject(thisWeather, "main");
 
                                if (main != null) {
                                    jsonResult += "temp: " + jsonHelperGetString(main, "temp") + "\n";
                                    jsonResult += "pressure: " + jsonHelperGetString(main, "pressure") + "\n";
                                    jsonResult += "humidity: " + jsonHelperGetString(main, "humidity") + "\n";
                                    jsonResult += "temp_min: " + jsonHelperGetString(main, "temp_min") + "\n";
                                    jsonResult += "temp_max: " + jsonHelperGetString(main, "temp_max") + "\n";
                                    jsonResult += "sea_level: " + jsonHelperGetString(main, "sea_level") + "\n";
                                    jsonResult += "grnd_level: " + jsonHelperGetString(main, "grnd_level") + "\n";
                                    jsonResult += "temp_kf: " + jsonHelperGetString(main, "temp_kf") + "\n";
                                    jsonResult += "\n";
 
                                }
                                JSONArray weather = jsonHelperGetJSONArray(thisWeather, "weather");
 
                                if (weather != null) {
                                    Log.d("Func", "Here" + "weather");
                                    for (int j = 0; j < weather.length(); j++) {
                                        JSONObject thisWeather1 = weather.getJSONObject(j);
                                        jsonResult += "weather " + ":\n";
                                        jsonResult += "id: " + jsonHelperGetString(thisWeather1, "id") + "\n";
 
                                        jsonResult += "main: " + jsonHelperGetString(thisWeather1, "main") + "\n";
                                        jsonResult += "description: " + jsonHelperGetString(thisWeather1, "description") + "\n";
                                        jsonResult += "\n";
                                    }
                                }
 
                                JSONObject clouds = jsonHelperGetJSONObject(thisWeather, "clouds");
                                String all = jsonHelperGetString(clouds, "all");
                                jsonResult += "clouds: " + all + "\n";
                                Log.d("Func", all);
                                JSONObject wind = jsonHelperGetJSONObject(thisWeather, "wind");
                                String speed = jsonHelperGetString(wind, "speed");
                                jsonResult += "speed: " + speed + "\n";
                                Log.d("Func", speed);
                                String deg = jsonHelperGetString(wind, "deg");
                                jsonResult += "deg:" + deg + "\n";
                                Log.d("Func", deg);
                                JSONObject rain = jsonHelperGetJSONObject(thisWeather, "rain");
                                String h = "3h:" + jsonHelperGetString(rain, "3h");
                                jsonResult += h + "\n";
                                JSONObject sys = jsonHelperGetJSONObject(thisWeather, "sys");
                                String pod = jsonHelperGetString(sys, "pod");
                                jsonResult += "pod:" + pod + "\n";
                                Log.d("Func", pod);
                                String dt_txt = jsonHelperGetString(thisWeather, "dt_txt");
                                Log.d("Func", dt_txt);
                                jsonResult += "dt_txt:" + dt_txt + "\n";
                            }
                        }
                    }
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        Log.d("Func", jsonResult);
        return jsonResult;
    }
Добавлено через 28 секунд
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
 private JSONObject jsonHelperGetJSONObject(JSONObject obj, String k) {
        JSONObject o = null;
        if (obj != null) {
            try {
                o = obj.getJSONObject(k);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return o;
    }
 
    private JSONArray jsonHelperGetJSONArray(JSONObject obj, String k) {
        JSONArray a = null;
        if (obj != null) {
            try {
                a = obj.getJSONArray(k);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return a;
    }
}
Добавлено через 50 секунд
Как можно исправить этот парсинг, чтобы предотвратить JSONException?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
09.07.2016, 22:55 18
yura91, эээ.... так вы картинку не загружаете в смысле слова "загрузить" = скачать по сети, а просто присваиваете какие-то судя по тематике облачка из уже имеющихся в ресурсах?
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,327
10.07.2016, 15:33  [ТС] 19
Не там по сети подружается но эту проблему я уже решил. А можете скинуть фрагмент как можно хранить Bitmap в Application и доставать его от туда при необходимости из разных компонентов приложения?
0
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,003
10.07.2016, 18:44 20
yura91, а может вы мне немного поможете показав как вы загружаете изображение ? Что то мне подсказывает что если в ваших руках после загрузки имеется байтовое представление изображения то вы можете его и хранить и сохранить
0
10.07.2016, 18:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.07.2016, 18:44

Как вызвать метод в активити классе из обычного не активити класса?
Есть активити в котором вводятся логин и пароль. При нажатии кнопки &quot;войти&quot; в...

Отображение активити поверх другого активити
Ребят подскажите пожалуйста как такое сделать. Есть активити с картой, по...

Вызов новой активити не из класса активити
Есть 4 класса: 1) WelcomeActivity; 2) MainActivity; 3) PopUpActivity; 4)...


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

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

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