Here are two Handler:
Handler handler1 = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_A:
break;
}
}
}
Handler handler2 = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ONE:
doSomethingOne();
break;
case MESSAGE_TWO:
doSomethingTwo();
break;
}
}
}
I can guarantee that MESSAGE_A and MESSAGE_ONE(or MESSAGE_TWO) will be sent in pairs, but don't know which one is the first. Now I want call doSomethingOne() only if handle MESSAGE_A and MESSAGE_ONE, call doSomethingTwo() only if handle MESSAGE_A and MESSAGE_TWO.
For example, I receive MESSAGE_ONE, now I need to wait for MESSAGE_A, then call doSomethingOne().
Similarly, I receive MESSAGE_A, now I need to wait for MESSAGE_TWO(or MESSAGE_ONE), then call doSomethingTwo()(or doSomethingOne).
What should I do?
Make sure the MESSAGE_A, MESSAGE_ONE, and MESSAGE_TWO are DIFFERENT.
write a method outside your handler classes, e.g. handleMessageTogether(message m)
in the method handleMessage() of your handler class, call the handleMessageTogether() method instead.
You can call handler2 from handler1 (when case message A). For example instead of sending messages messageone and messagetwo, you can do that with boolean, then when messageA is finished, call handler2 and see which boolean is true.
Related
First time ,i invoke HandlerThread.start() to handle the background service. after all the stuffs completed,I wanna to end this Thread by calling HandlerThread.quit().
Then the second time,I start this Handler,and checked the HandlerThread.isAlive(),the isAlive() return false, but when i invoke HandlerThread again by HandlerThread.start().
But I got the IllegalThreadStateException,why?
How can i really stop the HandlerThread before I invoke handlerThread.start() again safely?
onCreate(){
...............
CurrentLocationPresenter =
new CurrentLocationPresenter(getApplicationContext(),mHandler);
}
public void onClick(View v) {
int id = v.getId();
switch (id){
case R.id.showplacebutton:
showPlaceInMapActivity();
break;
case R.id.showgpsbutton:
if (mCurrentLocationPresenter.isAlive()){
break;
}
mCurrentLocationPresenter.start();
break;
private Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
if (msg.what == CurrentLocationPresenter.WHATCODE){
mCurrentLatlng = (LatLng) msg.obj;
mTextView.setVisibility(View.VISIBLE);
if (mCurrentLatlng!=null) {
mTextView.setText(mCurrentLatlng.toString());
}
mCurrentLocationPresenter.getLooper().quit();
}
}
};
As stated, you can never call the start/run/execute method on a thread object more than once, as you will get the IllegalThreadStateException.
You can, however, use something such as an ExecutorService which will allow you to use the same Runnable multiple times.
Also, if you use a ThreadPoolExecutor, which is a descendant of ExecutorService, the memory and thread management is taken care of.
You can't call asyntask.execute() on same object more than one.
Always call MyasynTask asyntask=new MyasynTask();
asyntask.execute();
for more enter link description here
I have the below handler
private Handler uiHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case UPDATE:
// Perform UI updates here
// UI Updates done, schedule WORK in 15 seconds:
this.sendMessageDelayed(this.obtainMessage(WORK), 15000);
break;
case WORK:
{
new Thread(checkUpdates).start();
}
break;
default:
super.handleMessage(msg);
}
}
};
Inside onResume() I do the following :
uiHandler.sendMessageDelayed(uiHandler.obtainMessage(WORK), 1000);
Inside onPause() I do the following
uiHandler.removeCallbacksAndMessages(null);
BUT the handler never stops and keeps on repeating.
How to stop it ?
(Side questions : is using timer task with flags whether the UI is still around to do some updates a better option)
I have the below handler :
public static final int WORK = 2;
public static final int UPDATE = 1;`
private Handler uiHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case UPDATE:
// Perform UI updates here
this.sendMessageDelayed(this.obtainMessage(WORK), 15000);
break;
case WORK:
{
new Thread(doWork).start();
}
break;
default:
super.handleMessage(msg);
}
}
};
This works super well.
However, the downside I am facing is the following.
Assume I run inside onResume() the following uiHandler.sendMessageDelayed(uiHandler.obtainMessage(WORK), 500);
Now the handler will run perfectly, lets say at time 9:00:10 , and will trigger to run the thread.
However, whenever I leave the activity, and go to another activity, then come back (rapidly) , another timer for the handler is starting.
Assume I came back from the other activity at 9:00:13
I will be having two threads running at both 9:00:15 and 9:00:28
And more if I go back and forth.
in my onPause I am calling uiHandler.removeMessages(WORK); but it is of no help.
I need to do some recursive tasks, say do something after every five seconds. How to achieve that? I will need to do the recursive task in the background, so I think I can go with a Started Service.
PS. What I am actually trying to do is: taking picture using camera after every five seconds, from a background service.
I found following code in the developer-guide. The method below resides in a custom class which extends Handler class:
#Override
public void handleMessage(Message msg) {
// Do Something
// HOW CAN i MAKE A RECURSIVE CALL (TO SOMEHOW CALL THIS FUNCTION) AFTER 5 SECONDS?
// Stop the service using the startId
stopSelf(msg.arg1);
}
}
Can I call something like Thread.sleep(5000) just before stopSelf()? (Not making sense to me...)
Or can I call something like this.sendMessageDelayed(msgOb, 5000); ?
Thanks.
Ok then this is one way to do with a handler:
int counter=0;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_TAKE_PIC:
if(counter==5) {
mHandler.removeMessages(MSG_UPDATE_CALLTIME);
break;
}
else {
//take pic here and then
counter++;
sendEmptyMessageDelayed(MSG_TAKE_PIC, 5000);
}
}
}
};
and where you want to start taking the pic just:
mHandler.sendEmptyMessageDelayed(MSG_TAKE_PIC, 5000);
I'm assuming you can modify the service that takes photos since you didn't say otherwise.
Why don't you just send a message for start to take photos and another for stop to take photos? The service will start taking photos every 5 seconds when you send the START message, until you send a STOP message.
Something like this:
class IncomingMessageHandler extends Hanlder implements Runnable {
private Boolean takePhotos = false;
public void handleMessage(Message msg) {
switch(msg.what) {
case START:
takePhotos = true;
new Thread(this).start();
break;
case STOP:
synchronized (takePhotos) {
takePhotos = false;
}
break;
}
}
public void run() {
while(takePhotos) {
takePhoto();
synchronized (takePhotos) {
takePhotos.wait(5000);
}
}
}
}
(this is the Service's hanlder implementation)
Is there any problem with using multiple Handlers in the same Activity.
I noticed that in all samples provided in android official website they use a single handler and detect different actions depending on the value of "what", is this because of memory management, and high amount of memory used by the Handler? Or should I call it "bad code" and do it the clean way (Multiple handlers each responsible for a specific task)
Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg) {
if (msg.what == 0){
// do something
}
else if (msg.what == 1){
// do something else
}
}
}
OR
Handler taskHandlerA = new Handler()
{
#Override
public void handleMessage(Message msg) {
// do something
}
}
Handler taskHandlerB = new Handler()
{
#Override
public void handleMessage(Message msg) {
// do something else
}
}
No there isn't such a limit (a Handler is just a message receiver), but if you want to do such a thing the more common approach is to have one Handler that you post Runnable objects to.
Here is some good reading on Loopers and Handlers.
When a Handler is created, it is automatically registered with its' Thread's Looper. This makes me think that you do not need multiple Handler's for a single thread. An Activity, specifically, one that uses multiple Thread's, could use multiple Handler's though.