Android: получаване на CalledFromWrongThreadException, въпреки че Runnable е публикуван в изгледа

Изправен съм пред странен проблем. Моят код има излъчващ приемник, който прави това в своя onReceive():

view.post(new Runnable() {
    @Override
    public void run() {
    view.refreshUI();
}});

Объркан съм относно причината този код да представя android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Вече публикувам обаждането refreshUI() вътре в Runnable на view. И така, как не работи на UI нишката?

Друго странно наблюдение е, че услугата за изпращане на излъчване дори не е изпратила излъчването в случая, когато виждам този срив. Знам това, защото има изявления, регистрирани в logcat както от страната на подателя, така и от страната на получателя. Но едно от тях присъства преди катастрофата.

За да дам малко предистория, горният код е написан в рамките на Android, за защита на клавиатурата (ИЛИ заключен екран). Работя върху изходния код на Android 4.3, който е персонализиран за нашия хардуер/платка.

Горният код е налице такъв, какъвто е от последните 1,5 години. Проблемът е видян само два пъти през последните няколко месеца, въпреки че нищо не е променено тук.

Вече минах през Изпълнение на UIThread и публикуване на изглед, все още получават CalledFromWrongThreadException и други подобни въпроси, но те се занимават предимно с AsyncTasks. Нямам AsyncTask в моя случай.

някакви мисли?


person Kiran Parmar    schedule 25.11.2015    source източник
comment
Използвайте Activity.runOnUIThread(new Runnable...)   -  person Nanoc    schedule 25.11.2015
comment
Не мога да го направя. Както споменах, моят код е в стандартната защита на клавиатурата на Android, която не е активност. Това е изглед, който е прикрепен към потребителския интерфейс директно през WindowManager.   -  person Kiran Parmar    schedule 25.11.2015
comment
Можете ли да направите ((Activity)view.getContext()).runOnUIThread...?   -  person Nanoc    schedule 25.11.2015
comment
@Nanoc Това не е дейност. Typecasting няма да работи. Използваният контекст е същият като този, създаден от процеса SystemServer.   -  person Kiran Parmar    schedule 25.11.2015
comment
Трябва да имате начин да извикате runOnUIThread, публикувайте повече от кода си, моля.   -  person Nanoc    schedule 25.11.2015
comment
Методът @Nanoc runOnUIThread() е достъпен само за Activity. Не мога да покажа моя код поради политиката на компанията, но мога да ви насоча към файла Andoird по подразбиране, който променям. Той е тук: android.googlesource.com/platform/frameworks/base/+/ Добавих метод refreshUI() тук и broadcastReceiver, който е регистриран в onFinishInflate(). Останалото е описано в моя въпрос.   -  person Kiran Parmar    schedule 26.11.2015
comment
Опитайте да използвате манипулатор като този: stackoverflow .com/questions/7860384/   -  person Nanoc    schedule 26.11.2015
comment
view.post() вътрешно извиква runnable на Handler. И така, как това е различно? Вижте кода тук: android.googlesource.com/platform/frameworks/base/+/   -  person Kiran Parmar    schedule 26.11.2015
comment
Не мога да видя извикването на getMainLooper, така че няма да се обзалагам, че е същото, можете ли просто да опитате?   -  person Nanoc    schedule 26.11.2015


Отговори (1)


Трябва да използвате runOnUiThread(), когато искате да актуализирате потребителския си интерфейс от нишка, която не е UI. Например - Ако искате да актуализирате потребителския си интерфейс от фонова тема. Можете също да използвате Handler за същото нещо.

трябва да използвате това:

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            view.refreshUI();
        }
    });
person Raul Mauricio Ramirez D    schedule 26.11.2015
comment
Искате ли да уточните за операцията? Само директните отговори не са много добри, дори ако отговарят на въпроса. - person Emz; 26.11.2015
comment
runOnUiThread не е наличен извън Activity. Както споменах във въпроса, този код не се изпълнява в дейност - person Kiran Parmar; 16.04.2019