Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
St@nton
3 / 3 / 0
Регистрация: 04.01.2013
Сообщений: 72
#1

Обновление GUI с высокой частотой - Программирование Android

11.11.2015, 15:39. Просмотров 393. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обновление GUI с высокой частотой (Программирование Android):

Посоветуйте, пожалуйста, монитор с высокой частотой обновления экрана - Мониторы
Посоветуйте, пожалуйста, монитор от 27 дюймов, с частотой обновления экрана от 75 Гц при full hd разрешении, и цене не более 15-20 тыр. ...

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

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

Обновление GUI-окна - Visual C++
Товарищи!!! Никак не могу обновить окно. Есть функция обратного вызова (не оконная), которая при получении данных посылает окну сообщение...

Как запустить qt gui программу, как демон, без gui, скрыв gui? - C++ Qt
Как запустить qt gui программу, как демон, без gui, скрыв gui? В gui браузер выполняет определенные действия, и нужно запустить этот...

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

9
Spelcrawler
527 / 497 / 111
Регистрация: 12.03.2014
Сообщений: 1,663
Завершенные тесты: 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 / 0
Регистрация: 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
2534 / 2013 / 627
Регистрация: 12.05.2014
Сообщений: 7,066
Завершенные тесты: 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 / 0
Регистрация: 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
2534 / 2013 / 627
Регистрация: 12.05.2014
Сообщений: 7,066
Завершенные тесты: 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
527 / 497 / 111
Регистрация: 12.03.2014
Сообщений: 1,663
Завершенные тесты: 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
Привет! Вот еще темы с ответами:

Как запустить GUI приложение (например, notepad.exe) без отображения GUI? - C++
Добрый день. Интересует есть ли такая возможность, как запустить GUI приложение (например, notepad.exe) без отображения GUI?

LWJGL и GUI - Выход из рендерного цикла для роботы в GUI без потери окна - OpenGL
Всем привет! Учусь использовать OpenGL в Java. И у меня возникла небольшая проблемка, окно LWJGL запускается с гуи, и если уже запустился...

LWJGL+ GUI - Выход из рендерного цикла для работы в GUI без потери окна - Java
Всем привет! Учусь использовать OpenGL в Java. И у меня возникла небольшая проблемка, окно LWJGL запускается с гуи, и если уже...

2 в высокой степени - Lazarus
var A: array of word; Nach: word; I,N,j: word; Perenos: integer; begin for i:=2 to 10000 do A:=0; A:=1; ...


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

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

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