I am developing app and I need that my app will be doing two actions at the same time. For example - I can drag marker and the map will be scrolling at the same time.
I tried to update map while dragging marker, everything would be okay, except thing that when thread starts, maps starts scrolling continuously and I cand do anything more. Here is the code, I call it in onCreate() method. I tried to do Runnable and AsyncTask and the results were the same. Any suggestions?
private void update() {
new Thread() {
public void run() {
while (true) {
runOnUiThread(new Runnable() {
#Override
public void run() {
while (drag)
mMap.animateCamera(CameraUpdateFactory.scrollBy(10, 0), 2, null);
}
});
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
You don't have the code to interrupt your thread. That's why your map keep scrolling. Try to use drag event to drive this animation, and add some code to terminate the thread at some point.
Related
Consider this example:
Thread thread = new Thread(new Runnable() {
public void run() {
// Sleep for 5000ms
// Show toast message
}
});
Now I will start this thread on button click in MainActivity and right after that I would exit the activity on back button press, but in overided method onBackPressed following code is implemented:
If(thread != null)
thread.interupt();
finish();
After few seconds toast message is shown, why is that?
interrupt, clears the interrupt status of your thread and will cause the InterruptedException to be thrown. So if your thread is sleepin, and while it is asleep, you call interrupt, it will be woken up, and the execution flow will continue from the instruction that follows the catch block. Assuming you have something really simple like:
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackThreace();
}
runOnUiThread(TOAST);
}
or
public void run() {
while(true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackThreace();
}
runOnUiThread(TOAST);
}
}
both will shown the Toast even though you called interrupt()
While blackbelt has already explained the reason why this happens, here is how you can get around the problem.
The best way to interupt a thread is to use a if-boolean-break method.
So if i were to re-write you code it would be along the following lines
onBackPressed:
isBackPressed = true;
inside the thread's run method:
Thread thread = new Thread(new Runnable() {
public void run() {
// Sleep for 5000ms
if(!isBackPressed){
// Show toast message
}
}
});
I am developing a 2 player board game with button clicks for moves y the 2 players. When playing with the device, I want it to pause before executing performClick() otherwise the move is too quick. I tried
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
b.performClick();
I have an animation listener before this that sets the status value in a textbox,but that is not getting written in the textbox. Please let me know how to solve this problem.Any help would be greatly appreciated. Thankyou!!
You shouldn't block the main thread. Use a Handler instead:
private final Handler mHandler = new Handler();
private void deferPerformClick() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
b.performClick();
}
}, 1000);
}
Good day everyone.
I'm working with AsyncTasks and calling publishProgress(); from doInBackground() method. I'm pretty sure there's no error until here.
I need to change an ImageView's source, e.g. in every 3 seconds from onProgressUpdate() method.
If i only do this;
agiz.setImageResource(R.drawable.image1);
initial image successfully changes to image1.
But if i try to do this (which is my goal actually)
imageView.setImageResource(R.drawable.image1);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
imageView.setImageResource(R.drawable.image2);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
imageView.setImageResource(R.drawable.image3);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
imageView WAITS 6 SECONDS, THEN turns to image3, without showing image2.
What am i missing ?
Thanks in advance.
I think you need a postDelayed method. It will be more readable and effective, because this method works in UI thread.
imageView.postDelayed(new Runnable(){
#Override
public void run() {
imageView.setImageResource(R.drawable.image1);
}}
,3000);
imageView.postDelayed(new Runnable(){
#Override
public void run() {
imageView.setImageResource(R.drawable.image2);
}}
,6000);
imageView.postDelayed(new Runnable(){
#Override
public void run() {
imageView.setImageResource(R.drawable.image3);
}}
,9000);
Explantation your problem.
I suppose that you block UI thread. Thread.sleep() method block current thread immediatly without waiting while your imageView was repainted, so you getting a lock result.
so I am building an experiment app where the background will change colour at random intervals.
I am stuck on the background change.
I have working code that changes the background colour, but when I put it in a thread/ try and catch bracket, the application is forced to close and doesnt give me an error?
Here is the code that works when used in the oncreate method:
View view = this.getWindow().getDecorView();
view.setBackgroundColor(Color.RED);
But when I want to make it "sleep" for 1 second and then change it to red, it bombs out.
Please note that this method is a separate method from the oncreate and is called from within there and will not work for some reason?
public void changeBackground(final View v){
Thread timer = new Thread(){
public void run(){
try{
sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}finally{
v.setBackgroundColor(Color.RED);
}
}
};
timer.start();
}
What am I doing wrong?
What I need:
when the app starts, it must wait for 1 second and then change the background colour without it bombing out.
Thanks in advance!
You cannot access UI thread from your custom thread. You have to run your runnable in UI thread. Change your changeBackground method to the following,
public void changeBackground(final View v) {
Thread timer = new Thread() {
public void run() {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
v.setBackgroundColor(Color.RED);
}
}
};
this.runOnUiThread(timer);
}
Or you can use Asynctask, this handles that issue for you. Here, and here.
Manipulate view state on UI thread:
v.post(new Runnable() {
#Override
public void run() {
v.setBackgroundColor(Color.RED);
}
});
More about it: http://developer.android.com/guide/components/processes-and-threads.html
UI operations can't be done in a Thread
v.setBackgroundColor(Color.RED);
Remove above line from finally and Use a runOnUIthread() to update UI in Finally.
and your final code will look like this
public void changeBackground(final View v){
Thread timer = new Thread(){
public void run(){
try{
sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}finally{
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
v.setBackgroundColor(Color.RED);
}
});
}
}
};
timer.start();
}
Solutions to fix this issue:-
Update you App
Clear Gmail Storage Data
Clear App Cache and Data
Reset App Preferences
Reset Smartphone Factory Settings
I found these steps with the help of YouTube.
Here is that link:-
youtube.com/watch?v=fx8Fv8RXag8
I have an ImageView, what shows one picture . I tried to use a thread, but it doesn't change the picture. Then I tried a handler, but it doesn't treat the sleep(int) method, so I can't increase the time, what elapsed. How can I make it? Can you write an example please?
Here is my original code:
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Thread timer = new Thread() {
public void run() {
int time = 0;
while (time <= 7000) {
try {
sleep(100);
time =+ 100;
if(time == 2000) {
radar.setImageResource(R.drawable.radar_full);
}
if(time == 5000) {
radar.setImageResource(R.drawable.radar_50);
}
if(time == 7000) {
radar.setImageResource(R.drawable.radar_found);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
timer.start();
};
};
Here are a couple of tutorials for you:
Android GUI thread timer sample
A Stitch in Time
It appears that you need to learn more about Threads and Handlers in general. However, it's worth pointing out that you cannot update a UI element from within a Thread, which is what I'm guessing you tried to do; UI updating (such as changing the content of an ImageView) must be done within the UI thread. Therefore, updating the image inside a Handler on the UI thread was going in the right direction. You just need a way to call that Handler at timed intervals, and the tutorial above demonstrates one such way, by simply posting messages to the Handler.