Четене от сокет буферен четец завинаги android

Опитвам се да направя просто приложение за чат сървър/клиент. Моят сървър е направен на python, използвайки twisted. Всичко работи добре с него, тествано е с telnet.

По принцип сървърът изпраща на всички свои клиенти всяко съобщение, което получава. Трябва ми начин да чета завинаги от сокета, за да мога да получавам всички съобщения. Не мисля, че това е най-добрият подход, но се опитах да го направя с помощта на нишка, която се чете завинаги (засега). След като клиентът се свърже със сървъра, той ще стартира нишка, която ще проверява завинаги за актуализации.

Ето моя клас CheckUpdates, който имплементира Runnable:

class CheckUpdates implements  Runnable{
    @Override
    public void run() {
       Log.d("ME", "CHECKING FOR UPDATES");
        while(true)
        {
            // reader.lines().forEach(System.out.println);
            String line;
            Log.d("ME","IN WHILE");
            try {
                while ((line = reader.readLine()) != null) {
                    Log.d("ME", "READING LINE");
                    Looper.prepare();
                    Toast.makeText(MainActivity.this, line, Toast.LENGTH_SHORT).show();
                    Looper.loop();
                }
            } catch (IOException e) {
                Log.d("ME", "EXCEPTION IN WHILE: " + e.getMessage().toString());
            }
            Log.d("ME", "END OF WHILE CHECK UPDATES");
        }
    }
}

Стартирам темата веднага след като се свържа със сървъра. По принцип получавам първото съобщение (първи тост) и веднага след това не идва нищо повече, дори съобщението КРАЙ НА ПРОВЕРКАТА НА АКТУАЛИЗАЦИИТЕ logcat.

Може ли да се блокира завинаги, докато проверява за нова линия от сокета? Също така, ако има по-елегантен начин да направите това, наистина ще съм благодарен, ако някой ме насочи в правилната посока.


person user1812076    schedule 18.12.2014    source източник


Отговори (2)


Може ли да остане завинаги през времето, когато проверява за нова линия от сокета?

Да, ако няма повече данни. Но подозирам, че не е това проблемът. Подозирам, че проблемът е следният:

Looper.loop();

Доколкото виждам, тук изобщо не е необходимо да използвате Looper. Ако приемем, че наистина сте в специална тема, какви съобщения очаквате да обработите? Тъй като нищо не извиква Looper.quit(), подозирам, че повикването Looper.loop() ще блокира завинаги.

Просто се отървете от двете Looper обаждания и подозирам, че ще можете да видите всички съобщения.

РЕДАКТИРАНЕ: Въпреки това ще трябва да покажете тоста в нишката на потребителския интерфейс - вижте този SO въпрос за подробности относно това, като използвате Activity.runOnUiThread. Не съм сигурен, че показването на тост за всяко съобщение е идеален потребителски интерфейс, имайте предвид...

Също така ще искате да се отървете от while (true) - вече работите по вътрешния цикъл, така че това е добре.

person Jon Skeet    schedule 18.12.2014
comment
Ако извадя looper, той ще хвърли изключение, защото не показвам тоста от UI нишката. Но да, изглежда, че Loooper.loop е проблемът. Как мога да актуализирам основната нишка от друга нишка без Looper? - person user1812076; 18.12.2014
comment
@user1812076: А, пропуснах това за тоста. Добре, така че трябва да направите само това в нишката на потребителския интерфейс с Activity.runOnUiThread. Вижте stackoverflow.com/questions/3134683/android-toast- в нишка - person Jon Skeet; 18.12.2014

Може ли да се блокира завинаги, докато проверява за нова линия от сокета?

Не, но може да остане завинаги във външния while (true) цикъл, което е напълно безсмислено. Премахни го. В момента зацикляте завинаги в края на потока.

person user207421    schedule 18.12.2014
comment
Искам да повтарям завинаги, защото искам да получа всички съобщения. Предполагам, че ако изчакам, ще получа само първото или ... ? - person user1812076; 18.12.2014
comment
@user1812076: Не, вече имаш цикъл while вътре, така че да преминаваш през всички редове. Наистина нямаш нужда от това while (true). (това ми липсваше...) - person Jon Skeet; 18.12.2014
comment
Напълно си прав. Ако не покажа никакъв Toast и просто проверя с logcat, всичко работи добре. Получавам всяко съобщение, но как мога да актуализирам нишката на потребителския интерфейс (или да покажа тост) с всяко съобщение? По принцип това е крайната цел. - person user1812076; 18.12.2014
comment
@user1812076 Не, вие не 'искате да циклите завинаги'. Искате да циклите до края на потока и това прави вашият вътрешен while цикъл. Вашият външен цикъл while е просто грешка. Не може да има никакви съобщения след края на потока. Смисълът на втория ти коментар ми убягва напълно. - person user207421; 18.12.2014
comment
прав си благодаря. Но все пак трябва да уведомя потребителя, че е пристигнало ново съобщение, как да покажа тост без looper или как да актуализирам елемент в потребителския интерфейс? - person user1812076; 18.12.2014
comment
Не съм експерт по Android, но изглежда, че вече го правите. Във всеки случай това е нов въпрос. - person user207421; 18.12.2014