Почему setBackgroundColor в макете иногда приводит к сбою моего приложения

Я создаю приложение, которое может отправлять и получать OSC. Я использую JavaOSC, он идеально подходит для моих нужд.

Я отправляю значение цвета в сообщении OSC и также получаю его.

Я отправляю цвет из палитры на основе этой палитры цветов http://code.google.com/p/color-picker-view/ отлично работает.

Моя проблема:

  • Когда я выбираю цвет в палитре цветов, я устанавливаю фон макета (где находится палитра цветов) с помощью:

частный ColorPickerView.OnColorChangedListener colorListener = новый ColorPickerView.OnColorChangedListener(){

    @Override
    public void onColorChanged(int color) {
        caller.sending("color", color);
        mScreen.setBackgroundColor(color);
    }
};

где mScreen — это LinearLyout

mScreen = (LinearLayout) findViewById(R.id.myScreen);

Он работает так, как ожидалось.

  • Когда я получаю сообщение OSC с цветом, я бы тоже хотел изменить фон, но оно вылетает.

мой слушатель

Слушатель OSCListener = новый OSCListener() {

        public void acceptMessage(java.util.Date time, OSCMessage message) {
            //en cas de message vide
            if (message.getArguments().length == 0) return;
            //sinon on recupere les elements et on les tries
            Object[] args = message.getArguments();
            if (args[0].toString().contains("alpha")) Log.i("receiver osc", "Message received!");

            //Instructions
            if (args[0].toString().contains("color")) {
                int color = (Integer)args[1];                   
                //mColorPickerView.setColor((Integer)args[1]);
                mScreen.setBackgroundColor(color);
            }
            else return;
        }

Вы можете найти отчет о сбое ниже. Должна ли функция setBackgroundColor быть в определенной функции для правильной работы (например, в функции onClick) или когда она перерисовывает что-то на экране?

Отчет о сбое

08-05 15:18:15.035: ПРЕДУПРЕЖДЕНИЕ/dalvikvm(18083): threadid=7: поток завершается с необработанным исключением (группа=0x4001d7d0) ОШИБКА/AndroidRuntime(18083): НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: ОШИБКА Thread-8/AndroidRuntime(18083): android.view.ViewRoot$CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может касаться своих представлений. ОШИБКА/AndroidRuntime(18083): в android.view.ViewRoot.checkThread(ViewRoot.java:2811) ОШИБКА/AndroidRuntime(18083): в android.view.ViewRoot.requestLayout(ViewRoot.java:594) ОШИБКА/AndroidRuntime(18083) : в android.view.View.requestLayout(View.java:8180) ОШИБКА/AndroidRuntime(18083): в android.view.View.requestLayout(View.java:8180) ОШИБКА/AndroidRuntime(18083): в android.view. View.requestLayout(View.java:8180) ОШИБКА/AndroidRuntime(18083): в android.view.View.setBackgroundDrawable(View.java:7535) ОШИБКА/AndroidRuntime(18083): в android.view.View.setBackgroundColor(View. java:7429) ОШИБКА/AndroidRuntime(18083): в com.taprik.Remote.RemoteMain$4.acceptMessage(RemoteMain.java:202) ОШИБКА/AndroidRuntime(18083): в com.illposed.osc.utility.OSCPacketDispatcher.dispatchMessage(Неизвестно Источник) ОШИБКА/AndroidRuntime(18083): в com.illposed.osc.utility.OSCPacketDispatcher.dispatchPacket(неизвестный источник) ОШИБКА/AndroidRuntime(18083): в com .illposed.osc.utility.OSCPacketDispatcher.dispatchBundle (неизвестный источник) ERROR/AndroidRuntime (18083): в com.illposed.osc.utility.OSCPacketDispatcher.dispatchPacket (неизвестный источник) ERROR/AndroidRuntime (18083): в com.illposed.osc .OSCPortIn.run(неизвестный источник) ERROR/AndroidRuntime(18083): в java.lang.Thread.run(Thread.java:1096) WARN/ActivityManager(6722): принудительное завершение действия com.taprik.Remote/.RemoteMain


person taprik    schedule 05.08.2011    source источник


Ответы (1)


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

Вы можете изменять элементы пользовательского интерфейса только в потоке пользовательского интерфейса: Примечание. Все, что выполняется в потоке пользовательского интерфейса, будет блокировать другие действия пользовательского интерфейса. Следовательно, если вы циклически просматриваете длинный список в потоке пользовательского интерфейса, пользователь не может взаимодействовать с пользовательским интерфейсом, пока это происходит.

MyActivity.this.runOnUiThread(new Runnable() {
    public void run() {
        mScreen.setBackgroundColor(color);
    }
});

Or:

private Handler mHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    /* ... */

    // Create the handler
    mHandler = new Handler();
}

private void changeBgColor(final int color) {
    mHandler.post(new Runnable() {
        public void run() {
            mScreen.setBackgroundColor(color);
        }
    }
}
person Austin Hanson    schedule 05.08.2011
comment
Перестанут ли когда-нибудь люди совершать эту ошибку? Просто для пояснения не запускайте все в этом run() ... только операторы, которые изменяют пользовательский интерфейс - person Sherif elKhatib; 05.08.2011
comment
Спасибо, Остин, run() работает в моем случае (изменения IU). Я начинаю с кодирования Android, и мне еще недостаточно ясно, как поместить функцию в поток пользовательского интерфейса. Я привык к функциям update() или draw() в С++. - person taprik; 05.08.2011