2

I am having an issue with removing a view from a WindowManager. Here is the method I am calling to do it:

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

It works perfectly when called from this onChange method initialized in the onCreate.

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

However, it fails when called from this, also initialized in onCreate.

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

Can I not call the updateDockNow from another thread? Why does it work in one case but not the other?

NOTE: This is not being run from an Activity, it is from a Service.

Thank you

-- ANSWER --

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 Answers1

1

Most View methods should be executed only from the main (UI) thread.

Activity.runOnUiThread() is your friend here.

Another option is to initialize a Handler in the UI thread, then keep it available to post() Runnables from each scheduled event. For example:

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);     
    }
}
matiash
  • 54,791
  • 16
  • 125
  • 154
  • Actually this is occurring in a Service. – biobombkitten May 02 '14 at 13:25
  • Ok. You should find another way to do it in the UI thread then. One possibility is to create a `Handler` instance in onCreate() and keep it around. Any messages post()'ed to it will be executed in the same thread that the Handler was created. – matiash May 02 '14 at 13:39
  • [link] (http://stackoverflow.com/questions/7539491/androids-activity-runonuithread-is-not-static-so-how-can-i-use-it) Is the bottom comment what you are referring to? What about the follow-up to that about it not running on the UI thread unless it was created there? – biobombkitten May 02 '14 at 13:41
  • As I understand it, your onCreate() method is running on the UI thread, no? Since you say operations on the WindowManager **do** work there, but not from the scheduled runnables. Therefore, creating the Handler in that method should bind it to that thread. – matiash May 02 '14 at 13:43
  • Thank you for your help I updated my question to include the solution I worked out. – biobombkitten May 02 '14 at 14:41
  • Well, your solution seems a tad too complicated, but ok :) – matiash May 02 '14 at 14:46