Не удается удалить представление из WindowManager — несколько потоков

У меня возникла проблема с удалением представления из WindowManager. Вот метод, который я вызываю для этого:

public void updateDockNow (String jsonData) {  
    getWM().removeView(getView());
    setView(new Stuff(jsonData));
    getWM().addView(getView(), getParams());
}

Он отлично работает при вызове из этого метода onChange, инициализированного в onCreate.

observer = new ContentObserver(new Handler()){
    @Override
public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    updateDockNow(DockPicker.getDockStringAsync(DockService.this));
}};

Однако при вызове из this происходит сбой, который также инициализируется в onCreate.

final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);       
scheduler.scheduleAtFixedRate(new Runnable() {
    public void run() { 
        if (decision) { updateDockNow(info); } // Problem
    }
}, 0, 1, TimeUnit.SECONDS);

Можно ли не вызывать updateDockNow из другого потока? Почему в одном случае работает, а в другом нет?

ПРИМЕЧАНИЕ. Это запускается не из действия, а из службы.

Спасибо

-- ОТВЕЧАТЬ --

final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);       
scheduler.scheduleAtFixedRate(new Runnable() {
    public void run() { 
        if (decision) { threadMsg(item); } // Problem
    }

    private void threadMsg(String msg) {
        if (!msg.equals(null) && !msg.equals("")) {
            Message msgObj = handler.obtainMessage();
            Bundle b = new Bundle();
            b.putString("message", msg);
            msgObj.setData(b);
            handler.sendMessage(msgObj);
        }
    }

    private final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            String reply = msg.getData().getString("message");

            if ((null != reply)) {
                Log.i(TAG, "SETTINGS UPDATED, hurray!");
                getWM().removeView(getView());
                setView(new Dock(DockService.this, reply));
                getWM().addView(getView(), getParams());
            }}
    };
}, 0, 1, TimeUnit.SECONDS);

person biobombkitten    schedule 01.05.2014    source источник


Ответы (1)


Большинство методов View должны выполняться только из основного (UI) потока.

Activity.runOnUiThread() твой друг здесь.

Другой вариант — инициализировать обработчик в потоке пользовательского интерфейса, а затем сохранить его. доступны для post() Runnables из каждого запланированного события. Например:

public class MyService extends Service
{
    private Handler mUiHandler;

    @Override
    public void onCreate()
    {
        super.onCreate();
        mUiHandler = new Handler();

        ContentObserver observer = new ContentObserver(...);

        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);       
        scheduler.scheduleAtFixedRate(new Runnable()
        {
            public void run()
            {
                mUiHandler.post(new Runnable()
                {
                    public void run()
                    {
                        updateDockNow(...);
                    }
                });
            }
        }, 0, 1, TimeUnit.SECONDS);     
    }
}
person matiash    schedule 01.05.2014
comment
На самом деле это происходит в службе. - person biobombkitten; 02.05.2014
comment
Ok. Тогда вам следует найти другой способ сделать это в потоке пользовательского интерфейса. Одна из возможностей — создать экземпляр Handler в onCreate() и сохранить его. Любые сообщения post() будут выполняться в том же потоке, в котором был создан обработчик. - person matiash; 02.05.2014
comment
[ссылка] (stackoverflow.com/questions/7539491/) Вы имеете в виду нижний комментарий? Как насчет продолжения того, что он не работает в потоке пользовательского интерфейса, если он не был создан там? - person biobombkitten; 02.05.2014
comment
Насколько я понимаю, ваш метод onCreate() работает в потоке пользовательского интерфейса, не так ли? Поскольку вы говорите, что операции в WindowManager работают там, но не из запланированных исполняемых модулей. Следовательно, создание обработчика в этом методе должно привязать его к этому потоку. - person matiash; 02.05.2014
comment
Спасибо за вашу помощь. Я обновил свой вопрос, включив в него решение, которое я разработал. - person biobombkitten; 02.05.2014
comment
Что ж, ваше решение кажется слишком сложным, но ладно :) - person matiash; 02.05.2014