The thread order issue in handler object - android

I have a handler object as below, just an example
My question is: if someone calls dataSync.setDataEnabled(true) then call dataSync.getDateEnabled() immediately. Can we make sure set/get still execute in order in dataSync class? Because we use message to write data but read data directly.
Thanks
class dataSync extends Handler {
...
#Override
public void handleMessage(Message msg) {
case CMD_SET_DATA_ENABLE_SYN:
final boolean enabled = ((boolean)msg.arg1) ? true : false;
setDataEnabledSync(enabled);
break;
}
public boolean getDateEnabled() {
sync (mLock) {
return mDataEnabled;
}
}
void setDataEnabled(boolean enable) {
Message msg = obtainMessage(CMD_SET_DATA_ENABLE_SYNC);
msg.arg1 = enable ? 1 : 0;
sendMessage(msg);
}
void setDataEnabledSync(enabled); {
sync (mLock) {
mDataEnabled = enabled;
}
}
}

The answer to the question is YES! It could be happen in this scenario.
"dataSync" this handler will queue the message and execute "in order call", BUT another thread will call "getDateEnabled()" immediately.
So when "dataSync" handler queue a lot messages it will go wrong.

Related

Correct approach for postDelay method of handler in the constructor

I have the following thread with a constructor in my service class.
public class communicationDetails extends Thread {
communicationDetails(final Handler _handler, final Handler conn_handler) throws IOException {
mhandler = _handler;
connHandler = conn_handler;
}
In onCreate in my service I tried to construct the thread and start it.First handler works fine, I could able to send messages. Since I want to post a message with delay, in the second handler I am trying to use postDelay method. This is where the problem comes in.
try {
communication_Details = new communicationDetails(
// works fine
new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(final Message msg) {
// sending messages
}
},
//this throws an error
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
// call a method
}
}, 2000));
} catch (IOException e) {
e.printStackTrace();
}
communication_Details.start();
I get following error. What stupid mistake am I doing here ? or is it completely wrong approach.
error: incompatible types: boolean cannot be converted to Handler
The error : incompatible types is because :-
handler.postDelayed(runnable) --> returns boolean
while the constructor requires object of type android.os.Handler
So you are basically passing boolean instead of an instance of Handler
For more info checkout android.os.Handler. ( cmd + click ) on Handler

Communication from App to a SystemService in Android

I'm essentially trying to create a SystemService in Android. I read that intercommunication from an app to this service should be handled by a Handler?
So what about returning some object from the Service's function to the calling app? How can this be handled.
To make my question more clear, Imagine I have a Service TestService with the following method definitions:
public class TestService extends ITestService.Stub {
public TestService(Context context) {
super();
mContext = context;
mWorker = new TestWorkerThread("TestServiceWorker");
mWorker.start();
Log.i(TAG, "Spawned worker thread");
}
public void setValue(int val) {
Message msg = Message.obtain();
msg.what = TestWorkerHandler.MESSAGE_SET;
msg.arg1 = val;
mHandler.sendMessage(msg);
}
public Object getValue() {
// ********************* QUESTION HERE *****************
// Can I call this method directly??
// Or do I have to process this through the handler?????
}
private class TestWorkerThread extends Thread {
public TestWorkerThread(String name) {
super(name);
}
public void run() {
Looper.prepare();
mHandler = new TestWorkerHandler();
Looper.loop();
}
}
private class TestWorkerHandler extends Handler {
private static final int MESSAGE_SET = 0;
#Override
public void handleMessage(Message msg) {
try {
if (msg.what == MESSAGE_SET) {
Log.i(TAG, "set message received: " + msg.arg1);
}
} catch (Exception e) {
// Log, don't crash!
Log.e(TAG, "Exception in TestWorkerHandler.handleMessage:", e);
}
}
}
}
This is what I understand from the above in order to be synchronous we generally make the setValue to be executed as part of the handleMessage()
What about the getValue method can make a call to this method using the Service instance and process it normally like how we do traditionally? Or do I have to work with the handler which is highly unlikely (I beleive). Kindly let me know the best process to deal with in this scenario.
Thanks
You don't HAVE to use a Handler to do any of that. If you've created an AIDL file that describes the communication with the service then you're done: all you have to do next is implement the AIDL methods inside your service.
When AIDL is translated into java code by the Android "compiler", you functions will all be blocking (the client will wait for the service to finish the methods).
If you specifically add the keyword 'oneway' then the method call won't be blocking.
You should check out Google's documentation on IBinder to understand things a little better.

Why thread terminates before loading all the data?

I am using Thread for loading library (Native code ) have to call some functions from the android code to the native code. it's working fine after some time thread terminating, so those functions are not calling properly. present i am using this code for thread creation.
class aThread extends Thread {
public static boolean finished;
public void run() {
if ( a_app.initApp() != 0) {
return;
} else {
}
a_app.startPjsua(ApjsuaActivity.CFG_FNAME);
finished = true;
a_app.deinitApp();
}
}
Is it correct process or not.?
Can i use any service for solving this problem, if yes how to create communication between activity and Service.
My requirement is i have to call a function in the background continuous upto app closes fully.? what is the best way to do like this.
Are you looking for something like this?
boolean ok;
onCreate(Bundle a)
{
...
ok=true;
new aThread().start();
}
class aThread extends Thread {
public static boolean finished;
public void run() {
while(ok==true)
{
if ( a_app.initApp() != 0) {
ok=false;
} else {
a_app.startPjsua(ApjsuaActivity.CFG_FNAME);
finished = true;
a_app.deinitApp();
}
//If you want to execute after some interval..
//Thread.sleep(time_in_milliseconds);
}
}
}
This way it will run as long as ok=true. When you exit the app or if you want to stop the thread; set the value of ok=false.

Recursively call handlerMessage from a started service?

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)

Periodic Message in Thread

I have a activity (myActivity) and a thread (MyThread) , both with a handler which allow me to send message between the UI thread and myCustomThread.
Now i would like to call periodically (10sec) the ALIVE message of the MyThread thread from MyActivity. How can i achieve that ?
MyActivity :
public void onResume()
{
super.onResume();
this.thread = new MyThread(activityHandler);
this.threadHandler = this.thread.gethandler();
threadMessage = this.threadHandler.obtainMessage();
threadMessage.what = AUTH;
this.threadHandler.sendMessage(threadMessage);
}
MyThread :
#Override
public void run()
{
Looper.prepare();
this.threadHandler = initHandler();
this.message = this.activityHandler.obtainMessage();
this.message.what = CONNECTED;
activityHandler.sendMessage(this.message);
Looper.loop();
}
private Handler initHandler()
{
return new Handler() {
public void handleMessage(Message msg)
{
switch(msg.what)
{
case AUTH :
{
auth();
break;
}
case ALIVE :
{
sendAlive();
break;
}
}
}
};
}
Thanks for your help
The correct solution really depends on what you are trying to put together...
This is a walk through for performing an action on a timer as well as how to use a delayed post (the preferred way of executing on a schedule because it doesn't use a thread for the timer). It is a good write up and they include the why.
Hope this helps.
I finally find a solution with sendEmptyMessageDelayed(ALIVE,10000)
Long story short, i call once ALIVE from my UI thread and at the end of the sendAlive() method i'm sending a delayedMessage to the thread itself to re-call ALIVE after X milliseconds.
With this solution no need of a new Thread or timer.

Categories

Resources