Im trying to get an ImageSwitcher to change an image every 5 secs..
I tried using a Timer:
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
currentIndex++;
// If index reaches maximum reset it
if(currentIndex==messageCount)
currentIndex=0;
imageSwitcher.setImageResource(imageIds[currentIndex]);
}
},0,5000);
But I get this error:
LOGCAT:
12-14 15:07:29.963: E/AndroidRuntime(25592): FATAL EXCEPTION: Timer-0
12-14 15:07:29.963: E/AndroidRuntime(25592): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
currentIndex++;
// If index reaches maximum reset it
if(currentIndex==messageCount)
currentIndex=0;
runOnUiThread(new Runnable() {
public void run() {
imageSwitcher.setImageResource(imageIds[currentIndex]);
}
});
}
},0,5000);
Only the original thread that created a view hierarchy can touch its views.
Timer task runs on a different thread. Ui should be updated on the ui thread.
Use runOnUiThread.
runOnUiThread(new Runnable() {
public void run() {
imageSwitcher.setImageResource(imageIds[currentIndex]);
}
});
You can also use Handler instead of timer.
Edit:
Check this setBackgroundResource doesn't set the image if it helps
Related
I have a textview, and I'm highlighting it dynamically (first 110 letters are highlighted first then after 1 second next 110 letters are highlighted and so on..). Below is my code for it.
I just created background thread as timer, but it is not stopping at all. How do I stop the timer after 3 iterations? Thanks in advance...
int x=0;,y=110//global values
Timer timer = new Timer();
//Create a task which the timer will execute. This should be an implementation of the TimerTask interface.
//I have created an inner class below which fits the bill.
MyTimer mt = new MyTimer();
//We schedule the timer task to run after 1000 ms and continue to run every 1000 ms.
timer.schedule(mt, 1000, 1000);
class MyTimer extends TimerTask {
public void run() {
//This runs in a background thread.
//We cannot call the UI from this thread, so we must call the main UI thread and pass a runnable
if(x==330)
Thread.currentThread().destroy();
runOnUiThread(new Runnable() {
public void run() {
Spannable WordtoSpan = new SpannableString(names[0]);
WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), x, y, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
x=x+110;
y=y+110;
textView.setText(WordtoSpan);
}
});
}
}
did you try Handler instead of timer Task?
private static int TIME_OUT = 3000;
//--------------
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// do your task here
}
}, TIME_OUT);
There are some disadvantages of using Timer
It creates only single thread to execute the tasks and if a task takes too long to run, other tasks suffer. It does not handle exceptions thrown by tasks and thread just terminates, which affects other scheduled tasks and they are never run
I simply want to change the bitmap image of an imageview on a set interval ( 2 seconds)
I have tried this but the app crashes:
private void prefromRadarInterval() {
int delay = 1000; // delay for 0 sec.
int period = 1000; // repeat every 1 seconds.
timer = new Timer();
timer.scheduleAtFixedRate(new SampleTimerTask(), delay, period);
}
public class SampleTimerTask extends TimerTask {
#Override
public void run() {
//MAKE YOUR LOGIC TO SET IMAGE TO IMAGEVIEW
imageview_radarcurrent.setImageBitmap(radar_animation[flag]);
flag++;
if(flag > 9) {
flag = 0;
}
}
}
The log cat prints this:
01-12 04:51:51.688: E/AndroidRuntime(19688): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Help and explanation would be appreciated!
Your problem is that the UI can only be modified buy the UI thread, and your TimerTask is running on it's own thread. The easiest way to solve this is probably by posting through a handler to the UI thread.
Take a look at this thread:Android timer updating a textview (UI)
You should call the setImageBitmap() from the UI thread.
For example:
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// Write your code here
}
});
... or post it with a Runnable:
imageview_radarcurrent.post(new Runnable() {
#Override
public void run() {
}
});
I would like to display a white rectangle periodically on the android screen; or change the background color. For example, every 500ms I want the screen color to change from black to white, for around 200ms, then back to black.
What is the best way to do this? I did try with an asynctask, but got an error that only the original thread can touch the View. I have a similar asynctask which sounds a periodic tone and that works fine.
SOLUTION:
With help from the responders I resolved my issue by creating two timers one for black and one for white. The black one starts delayed by the duration that I want to display the white screen. Both have the same execution rate, thus the white screen is displayed then, after duration ms the black screen is displayed. For example, the screen is black but flashes white every second for 200 ms.
#Override
protected void onResume() {
super.onResume();
mBlackTimer = new Timer();
mBlackTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
view.setBackgroundColor(Color.parseColor("#000000"));
}
});
}
}, duration, (long) (1000 / visionPeriod));
mWhiteTimer = new Timer();
mWhiteTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
view.setBackgroundColor(Color.parseColor("#ffffff"));
}
});
}
}, 0, (long) (1000 / visionPeriod));
}
You can use timer class for this to perform some task on repeated interval:
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
AsyncTask is mainly used to perform background thread activity like downloading data from remote server. It runs on it's own thread that's why when from the AsyncTask you try to access any View of your Activity it gives that Error that only the original thread can touch the View.
You may use Timer class or AlarmManager class for repetitive tasks. Visit my previous answer.
Create a Timer task method and inside the timertask and give it a periodic duration of 700ms show the black background and then create a handler for showing white background and post delay it for 500ms
try all of this in the uithread only
don't use new thread or asynctask
like this:
mTimer = new Timer();
mTtask = new TimerTask() {
public void run() {
//set your black background here
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// set your white background here
}
}, 500);
}
};
mTimer.schedule(mTtask, 1, 700);
public void displayCurrentLocation(){
mCurrentLocation=mLocationClient.getLastLocation();
TextView coordinates = (TextView)findViewById(R.id.coordinates);
coordinates.setText(mCurrentLocation.getLatitude()+", "+mCurrentLocation.getLongitude());
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
displayCurrentLocation();
}
}, 2000);
}
Just testing the concepts here. I am trying to get an updated current location every 2 seconds and display it in a TextView. I set this up so that it would do it once, but when I added the timer, it will setText once, but the next time it crashes. What is wrong?
I am trying to get an updated current location every 2 seconds and display it in a TextView.
My guess (based on above comment) is you are updating ui from a Timer task. Timer tasks runs on a different thread. You can't update ui from it. You need to update ui from a ui thread.
Use a Handler or runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
// update ui here
}
});
Handler is a better option.
http://developer.android.com/reference/android/os/Handler.html
When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
So if you create handler on the ui thread it is bound to it and you can update ui there.
Handler m_handler;
Runnable m_handlerTask ;
int timeleft=100;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something
m_handler.postDelayed(m_handlerTask, 2000);
}
};
m_handlerTask.run();
To cancel the run
m_handler.removeCallbacks(m_handlerTask); // cancel run
Timer runs in a separate Thread and where as you can not touch the UI views in non UI Thread...
use Handler of a TextView or runOnUiThread()
this may help you...
public void displayCurrentLocation() {
mCurrentLocation = mLocationClient.getLastLocation();
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView coordinates = (TextView) findViewById(R.id.coordinates);
coordinates.setText(mCurrentLocation.getLatitude() + ", "
+ mCurrentLocation.getLongitude());
}
});
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
displayCurrentLocation();
}
}, 2000);
I have the following type of application
Pull data prices down from feed
Process them and put them into my custom adapter
Display the prices in a ListView (so I call setAdapter).
Now the final stage is to repeat this infinitely perhaps at 5 second intervals.
So I have AsyncTask for handling the datadownload and on onPostExecute I update the adapter and it displays.
But how can I loop this whole activity with intervals of 5 seconds ?
Do I need to create a thread that calls this asynctask and in the thread use a loop with 5 second sleep ?
Thanks !!
You could use the TimerTask class and its scheduleAtFixedRate() method that download the data and after that update your interface using the post() method of a view so to avoid the AsyncTask at all. There are more way to do this, I should know because you want to download all every 5 seconds
The problem could be what to do when the datadownload fails or when it hangs for more than 5 seconds.
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
TimerMethod();
}
}, 0, 10000);
}
private void TimerMethod()
{
getActivity().runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
new AsyncTask().execute();
}
};