问题
Situation:
- activity binds to started foreground service.
- service hands out local binder to activity.
- activity gets reference to service through a getService() call.
- activity wants to communicate directly with a thread running in the service using messages. It calls the mService.getThreadHandler() method from the activity.
Problem:
- how do I get a Handler from the current running thread into the active activity, so that I can post messages directly to the threads messagequeue?
I don't what to use a messenger within the service, I want to directly communicate with the thread in the service from the activity side.
Edit: the activity gets the handler of the thread itself in the service, by calling something like this:
Activity code:
Handler mServiceThreadHandler;
ServiceConnection mServiceConnection;
public void onStart() {
if (!bindService(new Intent(this, MainService.class), mServiceConnection, Context.BIND_AUTO_CREATE))
{
Log.e(TAG, "Client did not bind to Service!");
}
super.onStart();
}
public class MyLocalServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocalBinder binder = (LocalBinder) service;
mService = (MainService) binder.getService();
// the handler of the service is actually a handler of a thread
// within the service, and is set automatically within the binding
// activity when binding to the service. That way you have a direct
// "connection" with the message queue of the thread instead of
// a message queue in the service itself (main thread of service)
mServiceThreadHandler = mService.getServiceHandler();
if (mServiceThreadHandler == null) {
Log.e(TAG, "Service handler is NULL");
}
mBoundedToService = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
mServiceThreadHandler = null;
mBoundedToService = false;
}
}
Service code:
private HandlerThread mServiceThread = new MyServiceThread();
public Handler getServiceHandler() {
return new Handler(mServiceThread.getLooper());
}
Does the new Handler(mServiceThread.getLooper()); return a new Handler or the same Handler within the mServiceThread?
Edit 2: updating the Service code with the serviceThread which receives the messages.
public class MyService extends Service {
private MyHandlerThread serviceThread = new MyHandlerThread("serviceThread");
serviceThread.start();
public Handler getServiceHandler() {
// hand out the same handler of the service thread for using it in an activity!
// serviceThread.getLooper() is the current looper of the thread
// serviceThread is the 'this' which handles the messages (see MyHandlerThread)
return new Handler(serviceThread.getLooper(), serviceThread);
}
// do stuff in Service
}
public class MyHandlerThread extends HandlerThread implements android.os.Handler.Callback {
public MyHandlerThread(String name) {
super(name);
}
public MyHandlerThread(String name, int priority) {
super(name, priority);
}
@Override
public boolean handleMessage(Message msg) {
// TODO define your own message handling here.
return false;
}
}
Correct?
回答1:
try this (i used Activity to test it you will use Service):
protected void onCreate(Bundle savedInstanceState) {
ht = new HandlerThread("HT");
ht.start();
htHandler = new Handler(ht.getLooper(), htCallback);
mainHandler = new Handler(mainCallback);
for (int i = 0; i < 10; i++) {
htHandler.sendMessageDelayed(htHandler.obtainMessage(99, i, 0), i * 3000);
}
}
private HandlerThread ht;
private Handler htHandler;
private Handler mainHandler;
private Callback htCallback = new Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.d(TAG, "handleMessage **********************");
Log.d(TAG, "handleMessage " + msg);
Log.d(TAG, "handleMessage Thread: " + Thread.currentThread());
if (msg.arg1 == 4) {
Log.d(TAG, "handleMessage sending back to Main thread");
mainHandler.sendEmptyMessage(101);
}
return false;
}
};
private Callback mainCallback = new Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.d(TAG, "handleMessage ########################");
Log.d(TAG, "handleMessage " + msg);
Log.d(TAG, "handleMessage Thread: " + Thread.currentThread());
Log.d(TAG, "handleMessage i'm quitting");
ht.quit();
return false;
}
};
来源:https://stackoverflow.com/questions/19541290/getting-a-handler-from-a-thread-from-service-to-activity