无法从WindowManager中删除视图 - 多个线程

时间:2014-05-01 20:31:50

标签: android multithreading scheduledexecutorservice window-managers

我遇到了从WindowManager中删除视图的问题。这是我打电话来做的方法:

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

从onCreate中初始化的onChange方法调用它时效果很好。

observer = new ContentObserver(new Handler()){
    @Override
public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    updateDockNow(DockPicker.getDockStringAsync(DockService.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吗?为什么它在一个案例中起作用而在另一个案例中却不起作用?

注意:这不是从一个Activity运行,而是来自服务。

谢谢

- 答案 -

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);

1 个答案:

答案 0 :(得分:1)

大多数View方法只能从主(UI)线程执行。

Activity.runOnUiThread()是你的朋友。

另一种选择是在UI线程中初始化Handler,然后使其可用于从每个预定事件发布()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);     
    }
}