Подтвердить что ты не робот

CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может касаться представлений

У меня есть проблема со следующей ошибкой в ​​Android:

CalledFromWrongThreadException;: Только исходный поток, который создал иерархия просмотра может касаться своих представлений

Похоже, что когда я пытаюсь обновить Textview в своей активности, вызов для обновления TextView происходит из моей активности, но я все еще получаю вышеуказанную ошибку.

У меня это так:

OnCreate() - устанавливает кнопки и текстовое представление.

onStateChange() - прослушиватель уведомлений об изменениях состояния, когда это получает уведомление, если TextView Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text -

Когда я получаю уведомление о новом тексте, я пытаюсь изменить TextView так:

((TextView)findViewById(R.id.title)).setText("Some Text");

Но я получаю вышеуказанную ошибку.

Из поиска в googling, кажется, я должен использовать обработчик для изменения TextView или, возможно, использовать AsyncTask?

Может ли кто-нибудь объяснить, какой из них лучше использовать и почему?

РЕДАКТИРОВАТЬ: СОЕДИНЕННЫЕ КОДЫ СОДЕРЖАНИЯ:


     public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);  

            setContentView(R.layout.my);

            getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_title);  

            ((TextView)findViewById(R.id.time)).setText("Hello Text");


            findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() {
                public void onClick(View v) {

                    Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"));
                    startActivity(dialIntent);

                        dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD));
                        dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));       
                }
        });

     }

//CallBacks from running Service

private final ICallDialogActivity.Stub iCallDialogActivity = new ICallDialogActivity.Stub(){

@Override
public void onStateChanged(int callState)
                throws RemoteException {    
            switch(callState){
            case GlobalData.CALL_STATUS_IDLE:

                break;

            case GlobalData.CALL_STATUS_DISCONNECTING:
                byeSetup();
                break;
    } 

};

public void byeSetup(){

            ((TextView)findViewById(R.id.time)).setText("Bye Text");

            findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    //Void the Button
                }});
}
4b9b3361

Ответ 1

Похоже, вы ошиблись. Попробуйте использовать Handler для обновления графического интерфейса в правой ветке. См. Обработка дорогостоящих операций в потоке пользовательского интерфейса с сайта android.com. В основном вы бы обернули byeSetup в Runnable и вызывают его с помощью экземпляра Handler.

Handler refresh = new Handler(Looper.getMainLooper());
refresh.post(new Runnable() {
    public void run()
    {
        byeSetup();
    }
});

Ответ 2

Расширение на willcodejavaforfood ответа для ясности и реализации...

Я получил это, чтобы работать, и ниже показано, как я это сделал. Я выполняю несколько потоков обработки в службе, поэтому другие решения, выполняемые в Activity, не работают, например runOnUiThread (новый Runnable() {}...

Поместите это вверху вашего класса обслуживания, чтобы он был доступен везде в этом классе:

Handler handler;

Поместите это в свой класс класса onCreate или что-то, что загружается в Основной поток службы

handler= new Handler(Looper.getMainLooper());

Поместите это внутри вашего дополнительного потока в код "post back", чтобы получить запуск в пользовательском интерфейсе или пользовательском интерфейсе службы (whatevers его вызвал):

handler.post(new Runnable() {
    public void run() {
        playNext(); //or whatever method you want to call thats currently not working
    }
});

Ответ 3

Для других просто замените byeSetup(); с вашими заявлениями или методами кода. byeSetup() - это метод выборки. Надеюсь, это сэкономит ваше время.

Ответ 4

когда изменение связано с основным потоком (UiThread). Используйте его внутри другого потока, чтобы изменить любое представление.

runOnUiThread(new Runnable() {
    @Override
    public void run() {

      // TODO your Code 
        et_Pass.setText("");
    }
});

Ответ 5

Другой подход, на этот раз использующий android.os.Message

Определите android.os.Handler как поле внутри вашей деятельности:

private final Handler myTextHandler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message stringMessage) {
        textView.append((String) stringMessage.obj);
        return true;
    }
});

Затем подайте его из другого потока следующим образом:

Message stringMessage = Message.obtain(myTextHandler);
stringMessage.obj = "Hello!";
stringMessage.sendToTarget();

Ответ 6

Вы можете использовать метод представления встроенного поста для обновления содержимого в другой ветке, как я использую текст редактирования в kotlin.

address_box.post { address_box.text="my text"}