Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
St@nton
3 / 3 / 2
Регистрация: 04.01.2013
Сообщений: 72
1

Обновление GUI с высокой частотой

11.11.2015, 15:39. Просмотров 454. Ответов 9
Метки нет (Все метки)

Всем привет. Есть приложение, которое соединяется с микроконтроллером через Bluetooth и выводит, поступающие с МК данные в EditText.

Обновление EditText происходит по вызову метода onMessageReceived(), который вызывается в методе onProgressUpdate() AsyncTask-а, т.е. в UI потоке.
Всё это работает, пока данные поступают не слишком быстро. Если же данные поступают каждые 10 мс, то UI подвисает.

Подскажете, что я не так сделал? Как обновлять GUI так часто (каждые 10 мс или чаще), чтобы он не вис?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.11.2015, 15:39
Ответы с готовыми решениями:

Посоветуйте, пожалуйста, монитор с высокой частотой обновления экрана
Посоветуйте, пожалуйста, монитор от 27 дюймов, с частотой обновления экрана от...

Сетевое программирование. Real-time обмен данными с высокой частотой
Доброго времени суток! требуется помощь. По постановке задачи мне необходимо...

Почему телевизоры с IPS матрицей делают с высокой частотой обновления, а мониторы - нет?
Говорят, что IPS матрицы медленные - у них не сделаешь высокое время отклика и...

Обновление GUI-окна
Товарищи!!! Никак не могу обновить окно. Есть функция обратного вызова (не...

Матрица: вывести название самой высокой вершины мира, самой высокой вершины заданной страны
Дан массив данных, в котором хранятся данные о вершинах гор: название, высота,...

9
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
11.11.2015, 16:03 2
St@nton, на совсем зависает или немного повисит и отпускает?
0
bastrakov
91 / 91 / 14
Регистрация: 10.10.2015
Сообщений: 307
Записей в блоге: 1
11.11.2015, 21:17 3
я бы собирал пачку данных некоторое время, и потом отдавал все разом.
0
St@nton
3 / 3 / 2
Регистрация: 04.01.2013
Сообщений: 72
12.11.2015, 00:43  [ТС] 4
Spelcrawler
Перестаёт висеть после некоторого времени. Но тогда и EditText перестаёт обновляться. Выглядит так, как будто EditText достигает максимального количества строк, которые он может вместить и перестаёт отображать новые строки, хотя данные по-прежнему идут.

bastrakov
Так я уже попробовал сделать, но смысла особого нет. Собираю в буфер сообщения в background-потоке, а потом в цикле прохожу по буферу и вызываю всю туже функцию onMessageRecevid(), которая должная быть вызвана в UI потоке, т.к. нужно обновить состояние UI-элемента (т.е. EditText ). Результат - всё тоже зависание.

Принимает сообщения из потока и отправляет их в UI

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
public class DataTransferHandler extends AsyncTask<String, String, String> {
 
    private SubModCallBack listener;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    private boolean connected;
 
    public DataTransferHandler(SubModCallBack listener, BluetoothSocket socket) throws StreamNotCreatedException {
        this.listener = listener;
        InputStream tmpIn;
        OutputStream tmpOut;
        connected = true;
        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            throw new StreamNotCreatedException(
                    StringValues.STREAM_NOT_CREATED.getText());
        }
        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }
 
    @Override
    protected String doInBackground(String... strings) {
        byte[] buffer = new byte[1024];  // buffer store for the stream
        int length; // bytes returned from read()
        String msg;
 
        // Keep listening to the InputStream until an exception occurs
        while (connected) {
            try {
                // Read from the InputStream
                length = mmInStream.read(buffer);
 
                for (int i = 0; i < length; i++) {
                    msg = "" + ((char) buffer[i]);
                    // Send the obtained bytes to the UI activity
                    publishProgress(msg);
                }
            } catch (IOException e) {
                return null;
            }
        }
        return null;
    }
 
    @Override
    protected void onProgressUpdate (String...values){
        listener.onMessageReceived(values[0]);
    }
 
    @Override
    protected void onPostExecute (String result){
        closeStreams();
        if (connected) {
            listener.onConnectionLost();
        }
    }
    /* Call this from the main activity to send data to the remote device */
    public boolean write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
            return true;
        } catch (IOException e) {
            return false;
        }
    }
 
    public void stopDataTransfer() {
        connected = false;
    }
 
    /* Call this from the main activity to shutdown the connection */
    private void closeStreams() {
        try {
            mmInStream.close();
            mmOutStream.close();
        } catch (IOException e) {
        }
    }
 
}


Метод из Activity, в которой обновляется EditText

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @Override
    public void onMessageReceived(String message) {
        // append the new string
        etMessages.append(""+(msgCounter++) +"_msg: " + message + "\n");
        // find the amount we need to scroll.  This works by
        // asking the TextView's internal layout for the position
        // of the final line and then subtracting the TextView's height
        final int scrollAmount = etMessages.getLayout().getLineTop(etMessages.getLineCount()) - etMessages.getHeight();
        // if there is no need to scroll, scrollAmount will be <=0
        if (scrollAmount > 0)
            etMessages.scrollTo(0, scrollAmount);
        else
            etMessages.scrollTo(0, 0);
    }
0
bastrakov
91 / 91 / 14
Регистрация: 10.10.2015
Сообщений: 307
Записей в блоге: 1
12.11.2015, 07:35 5
попробуйте сбрасывать в logcat. если проблемы исчезнут - виноват UI элемент, если нет - возможно проблемы канала.
0
Pablito
2732 / 2167 / 735
Регистрация: 12.05.2014
Сообщений: 7,586
Завершенные тесты: 1
12.11.2015, 16:19 6
а я бы запоминал время в миллисекундах, когда прилетает очередное обновление и если разница с текущим временем маленькая - не обновлять TextEdit
что-то типа
Java
1
2
3
        long now = System.currentTimeMillis();
        if (now - lastTime > 50) textView.setText("ololo");
        lastTime = now;
0
St@nton
3 / 3 / 2
Регистрация: 04.01.2013
Сообщений: 72
07.12.2015, 15:31  [ТС] 7
Сорри, был занят другим проектом.

Цитата Сообщение от bastrakov Посмотреть сообщение
попробуйте сбрасывать в logcat. если проблемы исчезнут - виноват UI элемент, если нет - возможно проблемы канала.
В логи без проблем выводит. Следуя вашему предположению, я заменил EditText на TextView. В этом случае зависания почти!! нет. Только когда выдвигаю Navigation Drawer, зависание чуток заметно, а так могу пользоваться UI-кнопками, вводить текст и отправлять его на МК. Почему такое разное поведениес с разными UI-элемнтами?

Цитата Сообщение от Паблито Посмотреть сообщение
а я бы запоминал время в миллисекундах, когда прилетает очередное обновление и если разница с текущим временем маленькая - не обновлять TextEdit
что-то типа
Так можно сделать, но я не могу терять сообщения, значит нужно собирать их в буфер. А про буфер я писал уже выше.



С одной стороны не удивительно, что gui виснет, ведь если данные приходят каждые 10 мс, то получаеся, что главный поток, практически, постоянно занят. Т.е. это почти то же, что написать в коде while(true) {} и запустить это в главном потоке. Может есть возможность создать какой нибудь, так сказать, subThread, т.е. второй UI-поток, который отвечал бы за обновление только EditText? Вот к примеру в том же BluetoothTerminal (не реклама) всё работает без зависаний даже при такой высокой частоте обновления UI-элемента. Там тоже всё в EditText выводится.
1
Pablito
2732 / 2167 / 735
Регистрация: 12.05.2014
Сообщений: 7,586
Завершенные тесты: 1
07.12.2015, 15:34 8
я в принципе об этом же и писал, обновлять TextView не каждый раз, а пропускать
0
bastrakov
91 / 91 / 14
Регистрация: 10.10.2015
Сообщений: 307
Записей в блоге: 1
07.12.2015, 15:49 9
кнопку не ту нажал. вместо ответа - отспасибкался. :-)
чет до меня только что дошло: зачем в поле редактирования(!) пихать что-то, что изменяется 100 раз в сек?!.
1) соглашусь с Паблито - показывайте реже.
2) может "отображать" не надо в поле для редактирования? может в чем-то другом? а поле редактирования использовать именно для "ручного ввода", для чего оно и было предназначено?

разница в скорости работы компонентов, очень часто, обьясняется евентами, которые ловит (и часто обрабатывает) данный компонент.
0
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
07.12.2015, 15:59 10
St@nton, по идее весь gui рассчитан на обновления раз в 16мс (60фпс). Больше уже не стоит делать. Можно просто хранить String(и его обновлять при получении новых данных) со всем списком. И отдельно от этого раз в 16мс обновлять ui из этого String'a.
0
07.12.2015, 15:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.12.2015, 15:59

Будет ли работать процессор Athlon XP с частотой FSB 200 МГц на материнской плате с максимальной частотой FSB 133 МГц?
Добрый день, подскажите пожалуйста будет ли работать процессор Athlon XP с...

Как запустить qt gui программу, как демон, без gui, скрыв gui?
Как запустить qt gui программу, как демон, без gui, скрыв gui? В gui браузер...

[ubuntu] Как запустить qt-gui программу без gui-интерфейся из консоли?
Как запустить qt-gui программу без gui-интерфейса из консоли?


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

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

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