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.
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'm calling methode doSomething() continuously with a thread.sleep(100). This happens in on the UIThread, so the UIthread gets unresponsive. What is the correct way in Android to run the method doSomething() or the entire someobject in a seperate thread?
public void loop(){
while(true){
someObject.doSomething();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Right now i'm using
new Thread(new Runnable() {
#Override
public void run() {
someObject.doSomething();
}
}).start();
This obviously creates a different thread for each iteration. I don't think this is the correct way. What is the correct way in Android?
new Thread(new Runnable() {
#Override
public void run() {
while(true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
someObject.doSomething();
}
}
}).start();
Since run never returns, the thread will never end and will loop forever. It will call doSomething roughly every 100 ms (as close as sleep will get, which isn't exact).
You can make your own Thread class, with Looper and Handler, posting your doSomething every 100ms:
public class MyThread extends Thread{
private Handler myHandler;
#Override
public void run(){
Looper.prepare();
myHandler = new Handler();
myHandler.post(doSomethingRunnable);
}
Runnable doSomethingRunnable = new Runnnable{
doSomething(); //or myHandler.postDelayed() first for greater accuracy, but only if doSomething doesnt take too long
myHandler.postDelayed(doSomethingRunnable, 100);
};
doSomething(){
thisStuff(thatStuff());
}
}
You can use AsyncTask. doInBackground() is called on a background thread and will not block UI. This is the preferred way for doing stuff on background threads.
For a long running task. You can use an IntentService and put your background code in onHandleIntent
You can use a basic thread but it may be hard to manage. You can read more about threads in android here
I wants to create a custome Input Method with word suggestions from a webservice in an asynchronous way. If it is not asysnchronouse , phone get stuck while connecting to internet. If I use Thread it cause an excpetion "ui can be touch only by the tread created ". I don't know runOnUIthread can be used or how. I understood that runOnUiThread activity method. Anybody please help. I used android Example app softkeybord.
I'm not sure I understand,
If the definition of the Thread is inside the Activity,
You can just call:
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
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'm working on a service and I had the following code in onStartCommand:
try {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Networker.get("http://google.com/");
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.run();
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Even though the networking code is running in another thread, my service still crashed with the NetworkOnMainThreadException. The equivalent AsyncTask code does not cause this error. Is it because of the join?
I was doing this because I only need my service to run a single request and then quit, so I wanted to use the code above and return START_NON_STICKY to make the service close quickly again. Am I supposed to be doing something else instead?
Call start() and not run() on the thread to start the thread.
run() will just run your Runnable in the current thread.