Periodic Message in Thread - android

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.

Related

condition signal from handler postDelayed?

I'm very new to Android programming so pls excuse my ignorance...
I'm trying to do simple Android app:
User presses a button, starts postDelayed job and then waits on conditional var
after timeout the postDelayer job should signal
private final static long TIMEOUT = 10000;
private Handler mHandler;
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
#Override
protected void onCreate(Bundle savedInstanceState) {
...
mHandler = new Handler();
...
}
private void timeOutSignal() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
Log.d(">> ", "---> timeout notify");
lock.lock();
try {
condition.signal(); // releases lock and waits until doSomethingElse is called
} finally {
lock.unlock();
}
}
}, TIMEOUT);
}
public void buttonClick(View view) {
timeOutSignal();
Log.i("???", "... WAIT");
lock.lock();
try {
condition.await();
} catch (InterruptedException e) {
// todo
} finally {
lock.unlock();
}
Log.i("???", "... WAIT DONE !");
}
What happens is that buttonClick() is stuck waiting and I'm not even seeing the "---> timeout notify" message after timeout...
What I'm doing wrong ?
EDIT: Tried to fix messed up example...
You can't do what you're trying to do. Handlers run on Looper threads. Handlers that are created with the default constructor will use Looper thread that it is currently running in. In this case, it is the main Looper thread (or UI thread). So, you're locking on the UI Thread and the Handler unlocks on the UI Thread, but it will never reach that point because you're blocking the UI Thread.
Also, at no point do I see you actually calling the method that posts to the Handler.

Android, creating a simple thread that will updated my seconds counter

Basically, I am trying to run a seconds counter and a levels counter. For every 10 seconds I want to ++level.
But that's not implemented as yet, so far I am just trying to get the seconds to display but I am getting runtime exceptions and a crash.
Googling I see that its because I am trying to update the UI from my thread and thats not allowed.
So I guess I am going to need asyncTask, but I have no idea how to do that with my simple little program. Please help or give me some alternatives...
package com.ryan1;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class main extends Activity {
int level = 1;
int seconds_running=0;
TextView the_seconds;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
the_seconds = (TextView) findViewById(R.id.textview_seconds);
Thread thread1 = new Thread(){
public void run(){
try {
sleep(1000); Log.d("RYAN", " RYAN ");
updated_secs();
} catch (Exception e) {
e.printStackTrace();
Log.d("RYAN", " "+e);
}
}
};
thread1.start();
}
public void updated_secs(){
seconds_running++;
the_seconds.setText(" "+seconds_running);
}
}
Create a Handler in your UI thread, then in the worker thread send a message to the handler (Handler.sendMessage(...)).
The message will be processed on your UI thread, so you can update the text widget correctly. Like this:
private Handler myUIHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
if (msg.what == some_id_you_created)
{
//Update UI here...
}
}
};
Then in your thread, to send a message to the handler you do this:
Message theMessage = myHandler.obtainMessage(some_id_you_created);
myUIHandler.sendMessage(theMessage);//Sends the message to the UI handler.
For this kind of thing, it is a waste to use another thread; it is just a waste and makes it so you have to dael with multithreading issues. Instead, just use Handler.sendDelayedMessage():
static final int MSG_DO_IT = 1;
static final long TIME_BETWEEN_MESSAGES = 10 * 1000; // 10 seconds
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_DO_IT: {
// Update your UI here...
Message newMsg = obtainMessage(MSG_DO_IT);
sendMessageDelayed(newMsg, TIME_BETWEEN_MESSAGES);
} break;
}
}
}
#Override
void onResume() {
super.onResume();
// Start the timer, executing first event immediately.
Message newMsg = mHandler.obtainMessage(MSG_DO_IT);
mHandler.sendMessage(newMsg);
}
#Override
void onPause() {
super.onPause();
// Stop the timer.
mHandler.removeMessages(MSG_DO_IT);
}
Note that this implementation will have some drift -- the actual time between messages is TIME_BETWEEN_MESSAGES + (time to dispatch message). If you need something that won't drift, you can do the timing yourself by using Hander.sendMessageAtTime() and incrementing the new time with a constant value each time, starting with an initial time you get with SystemClock.uptimeMillis() in onResume().
There is a great example of a Timer built using AsyncTask and a Handler with the postDelayed method.
You are correct that updating the UI from a background is a no-no.

A common class for asynctask UI handling

I have used a lot of asynctask class in my application. Is it possible to write common class and update the user interface value?
As long as Java has no closures, I don't think this makes a lot of sense.
If you are always doing the same task and only want to modify different UI elements, you can go and pass them in a constructor and then later modify them in onPostExecute().
Instead of using async tasks you can post messages to a common handler to handle UI messages
Common UI handler
private Handler messageHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
//handle update
//.....
}
}
};
Thread to post the message
Thread t = new Thread() {
public void run() {
while (true) {
mResults = doSomethingExpensive();
//Send update to the main thread
messageHandler.sendMessage(Message.obtain(messageHandler, mResults));
}
}
};
t.start();
}

MultiThreading issues while programing for android

I am developing on Android but the question might be just as valid on any other Java platform.
I have developed a multi-threaded app. Lets say I have a first class that needs to do a time-intensive task, thus this work is done in another Thread.
When it's done that same Thread will return the time-intensive task result to another (3rd) class.
This last class will do something and return it's result to the first-starting class.
I have noticed though that the first class will be waiting the whole time, maybe because this is some kind of loop ?
Also I'd like the Thread-class to stop itself, as in when it has passed it's result to the third class it should simply stop. The third class has to do it's work without being "encapsulated" in the second class (the Thread one).
Anyone knows how to accomplish this ?
right now the experience is that the first one seems to be waiting (hanging) till the second and the third one are done :(
If you want to use threads rather than an AsyncTask you could do something like this:
private static final int STEP_ONE_COMPLETE = 0;
private static final int STEP_TWO_COMPLETE = 1;
...
private doBackgroundUpdate1(){
Thread backgroundThread = new Thread() {
#Override
public void run() {
// do first step
// finished first step
Message msg = Message.obtain();
msg.what = STEP_ONE_COMPLETE;
handler.sendMessage(msg);
}
}
backgroundThread.start();
}
private doBackgroundUpdate2(){
Thread backgroundThread = new Thread() {
#Override
public void run() {
// do second step
// finished second step
Message msg = Message.obtain();
msg.what = STEP_TWO_COMPLETE;
handler.sendMessage(msg);
}
}
backgroundThread.start();
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
switch(msg.what){
case STEP_ONE_COMPLETE:
doBackgroundUpdate2();
break;
case STEP_TWO_COMPLETE:
// do final steps;
break;
}
}
}
You would kick it off by calling doBackgroundUpdate1(), when this is complete it sends a message to the handler which kicks off doBackgroundUpdate2() etc.
Tiger ,
TiGer wrote:
When it's done that same Thread will
return the time-intensive task result
to another (3rd) class
Since thread runs asynchronously so your non-thread class can't be synced with your thread
Though to perform some action on an Activity you need an AsyncTask not A Thread
TiGer wrote:
maybe because this is some kind of
loop ?
Tiger do read more about Threads and concurrency
So the only answer I have for you now is ASYNCTASK
EDIT:
Also I'd like the Thread-class to stop
itself
Read this post's how-do-you-kill-a-thread-in-java
In ordinary Java, you would do this:
class MyTask implements Runnable {
void run() {
for (int i = 0; i < Integer.MAX; i++) {
if (i = Integer.MAX -1) {
System.out.println("done");
}
}
}
}
class MyMain {
public static void main(String[] argv) {
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new MyTask());
t.start();
}
System.out.println("bye");
}
}
... that kicks off 10 threads. Notice that if you accidentally invoke t.run() instead of t.start(), your runnable executes in the main thread. Probably you'll see 'bye' printed before 10 'done'. Notice that the threads 'stop' when the the run() method of the Runnable you gave to them finishes.
I hope that helps you get your head around what it is you've got to co-ordinate.
The tricky part with concurrency is getting threads to communicate with each other or share access to objects.
I believe Android provides some mechanism for this in the form of the Handler which is described in the developer guide under designing for responsiveness.
An excellent book on the subject of concurrency in Java is Java Concurency in Practice.
if you want use AsyncTask rather then thread in android
I have resolve it using ASyncTask and Handler in Android the aim is that one task is execute after compilation of one task hear is code that show First load animation on view after compilation of that process it will goes on another page
class gotoparent extends AsyncTask<String,String,String>
{
#Override
protected String doInBackground(String... params) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Animation animation= AnimationUtils.loadAnimation(getApplicationContext(),R.anim.rotete);
lin2.startAnimation(animation);
}
});
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i=new Intent(getApplicationContext(),ParentsCornor.class);
startActivity(i);
}
}, 1200);
}
}

How to update UI via Handler

So, I am getting an error that I am updating the UI from the wrong thread. This of course was not my intention. My case is quite long, but I will try to do it justice with code snippets. My end goal is to run an expensive task in a separate thread and post update that happen along the way and at the end to my listView.
public class test extends Activity {
private ArrayAdapter<String> _mOutArrayAdapter;
private ListView _mOutView;
private EditText _mCmdEditText;
private Button _mRunButton;
private Interpreter _interpreter;
// Need handler for callbacks to the UI thread
public final Handler _mHandler = new Handler() {
public void handleMessage(Message msg) {
_mOutArrayAdapter.add(msg.getData().getString("text"));
};
};
// Create runnable for posting
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi();
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_interpreter = new Interpreter(true);
_mOutView = (ListView)findViewById(R.id.out);
_mCmdEditText = (EditText)findViewById(R.id.edit_command);
_mRunButton = (Button)findViewById(R.id.button_run);
_mOutArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
_mOutView.setAdapter(_mOutArrayAdapter);
_mOutArrayAdapter.clear();
_interpreter.setOutputAdapter(_mOutArrayAdapter);
Thread t = new Thread() {
public void run() {
_mResults = _interpreter.executeExpression("startup;",_mHandler);
_mHandler.post(mUpdateResults);
}
};
t.start();
);
And then inside inpterpreter I do this:
public class Interpreter
{
private static Handler _mHandler;
public String executeExpression(String expression, Handler handler)
{
_mHandler = handler;
//Do a bunch of stuff that sometimes calls displayText from this class or from others
return answer;
}
public void displayText(String text)
{
Message msg = new Message();
Bundle bndl = new Bundle();
bndl.putString("text", text);
msg.setData(bndl);
_mHandler.dispatchMessage(msg);
}
}
The display of the final answer works. And the dispatchMessage is ending up triggering handleMessage, but it throw an error that I cannot modify the UI from outside of the UI thread which I know is illegal. So, what am I doing wrong?
Thanks!
_mHandler.dispatchMessage(msg);
dispatchMessage() causes the Handler to be run on the current thread.
http://developer.android.com/reference/android/os/Handler.html
dispatchMessage(Message msg)
Handle system messages here.
You should be using _mHandler.sendMessage(msg); It will put the message on the queue to be run by the Thread that declared the Handler.
sendMessage(Message msg)
Pushes a message onto the end of the message queue after all pending messages before the current time.
I would strongly suggest you stick with an AsyncTask (or one of the droid-fu versions if you need rotation/background support) unless you know what you're getting into. It'll help you cleanly keep track of what code is running in your UI thread and what code is in the background task, and save you a lot of confusion that dealing with Threads and Handlers yourself can cause.
Handler's post method requires a Runnable object in parameter, and scheduling execution of that runnable block. Instead you can use Handler.sendEmptyMessage() or Handler.sendMessage() to send a message to Handler. SO change your code to following:
Thread t = new Thread() {
public void run() {
_mResults = _interpreter.executeExpression("startup;",_mHandler);
Message msg= _mHandler.obtainMessage();
msg.obj= _mResults;
_mHandler.sendMessage(msg);
}
};

Categories

Resources