#Override
public void run() {
act.runOnUiThread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < randomNumber.size(); i++) {
Log.d("N",randomNumber.get(i).toString());
if (randomNumber.get(i).intValue() == 1) imgColor.setBackgroundColor(Color.RED);
if (randomNumber.get(i).intValue() == 2) imgColor.setBackgroundColor(Color.GREEN);
if (randomNumber.get(i).intValue() == 3) imgColor.setBackgroundColor(Color.BLUE);
if (randomNumber.get(i).intValue() == 4) imgColor.setBackgroundColor(Color.YELLOW);
try {
Thread.sleep(1750);
} catch (Exception e) {
Thread.currentThread().interrupt();
}
imgColor.setBackgroundColor(Color.BLACK);
try {
Thread.sleep(400);
} catch (Exception e) {
Thread.currentThread().interrupt();
}
}
Toast.makeText(act, "Ripeti la sequenza", Toast.LENGTH_SHORT).show();
}
});
}
I have a number list, with numbers from 1 to 4. I want to picture the ImageView according to the numbers in the list, but I need a sequence of colors, so I need (for example) show the RED color, after wait 1,75 seconds, and after the GREEN and so on, but it doesn't work ! What should I do ?
For such tasks Thread isn't the best choice. I recommend you to use View.postDelayed method. So you should get something like that.
void setRandomColor(){
if(!hasRandomColor())
return;
imgColor.setBackgroundColor(getRandomColor());
imgColor.postDelayed(new Runnable(){
void run(){
setRandomColor();
}
}, 1750); // update color again after 1.75 sec
}
...
setRandomColor();
Related
I am trying to stop the for loop and wait until the method has finished and continue once it has called onFinish. I was suggested to use either CyclicBarrier or syncronized wait/notify, but neither of them work.
When I run the method without the "stoppers", it always reaches to the onFinish, calling all 3 System.out.prints, but when I add either CyclicBarrier or syncronized it just does not start ticking. Meaning it only prints the first line countDownTimer first call and then stops and does nothing.
Just to make it shorter I have added both stoppers here to show how I did either of them, but I did use them seperately.
What can I do to make it "tick" ?
cyclicBarrier = new CyclicBarrier(2);
object = new Object();
for (int i = 0; i < sentenceList.size() - 1; i++) {
String currentLyricLine = sentenceList.get(i).content;
long diff = sentenceList.get(i+1).fromTime - sentenceList.get(i).fromTime;
int interval = (int) (diff / sentenceList.get(i).wordCount);
if(isFirstLine) {
startLyricCountDownTimer(diff, interval, currentLyricLine, coloredLyricsTextViewFirstLine);
isFirstLine = false;
} else {
startLyricCountDownTimer(diff, interval, currentLyricLine, coloredLyricsTextViewSecondLine);
isFirstLine = true;
}
//First tried with this
synchronized (object) {
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Then tried with this
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
private void startLyricCountDownTimer(final long millisInFuture, final int countDownInterval, String lyrics, final ColoredLyricsTextView coloredLyricsText){
System.out.println("countDownTimer first call" );
coloredLyricsText.setText(lyrics);
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
new CountDownTimer(millisInFuture,10) {
#Override
public void onTick(long millisUntilFinished) {
System.out.println("countDownTimer second call + " + millisUntilFinished);
//Do some stuff (irrelevant since it never gets here)
}
#Override
public void onFinish() {
System.out.println("countDownTimer last call" );
//First tried with this
synchronized (object) {
object.notify();
}
//Then tried with this
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}.start();
}
});
}
If i understand correctly then it was also mentioned that I run my loop on UI thread which is why everything stops. And well I do not wish to stop the UI thread, just to wait for one countDownTimer to finish, then start a new loop.
I have a android that draws a mandelbrot image.
I have 16 threads that each draw 1/16 part of the image, they have their own bitmap.
for(int x=0;x<xw;x++) {
for(int y=0;y<yh;y++) {
c_real=realMin+((double)(x+x1)*scaleReal);
c_imag=imagMin+((double)(y+y1)*scaleImag);
tmp=cal_pixel(c_real, c_imag, mag);
while(pause[thread]) {
try{
Thread.sleep(5);
}catch(InterruptedException ie){
}
}
plot(x,y,c[tmp], thread);
active[thread]=true;
}
dirty=true;
}
public void plot(int x, int y, int c, int myId) {
bitmap[myId].setPixel(x, y, c);
}
The run method for each piece
public void run() {
int myId=id++;
Log.i("run","Starting thread "+myId);
while(true) {
if (redraw[myId]) {
Log.i("run","redraw");
calc(myId);
redraw[myId]=false;
}
try{
Thread.sleep(100);
}catch(InterruptedException ie) {
}
}
}
I have a separate thread that 10 times a second takes the bitmaps and draws them on the canvas.
image.pause(true);
for(int i=0;i<16;i++) {
c.drawBitmap(image.getBitmap(i), (i%4)*w/4, (i/4)*h/4, null);
}
image.pause(false);
This is the thread that draws them
public void run() {
Canvas c;
while (true) {
if (run) {
if (view.dirty()) {
c = null;
try {
c = holder.lockCanvas(null);
synchronized (holder) {
view.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
holder.unlockCanvasAndPost(c);
}
}
}
try{
Thread.sleep(100);
}catch(InterruptedException ie){
}
}else{
//Log.i("Waiting the night away","Waiting the night away");
try{
Thread.sleep(1000);
}catch(InterruptedException ie){
}
}
}
}
Sometimes one or several of these pieces gest screwed up and are not drawn to the canvas, any idea why that happense.
It worked better in android 2.3.x it almost never happened, but noww in android 4.x it happens qquite often, if you want to check the program out and experience the bug here is the link https://play.google.com/store/apps/details?id=se.klockar.mandelbrotmobile
Iam making app for listening .mp3 words in greek language and displaying them after 2000ms but when i pause thread and then notify() back thread never runs again... TextView is changing every 2000ms but when i pause it and notify() run() block is not executing anything anymore and app crashes.. What iam doing wrong ?
class MyinnerThread implements Runnable {
String name;
Thread tr;
boolean suspendFlag;
int i = 0;
MyinnerThread(String threadname) {
name = threadname;
tr = new Thread(this, name);
suspendFlag = false;
tr.start();
}
public void run() {
try {
while(!suspendFlag){
runOnUiThread(new Runnable() {
#Override
public void run() {
if(i == 0){tv1.setText("trhead1");}
if(i == 1){tv2.setText("trhead2");}
if(i == 2){tv3.setText("trhead3");}
if(i == 3){tv4.setText("trhead4");}
if(i == 4){tv5.setText("trhead5");}
if(i == 5){tv6.setText("trhead6");}
if(i == 6){tv7.setText("trhead7");}
if(i == 7){tv8.setText("trhead8");}
synchronized(signal) {
while(suspendFlag) {
try {
signal.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread.sleep(2000);
i++;
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
}
void mysuspend() {
suspendFlag = true;
}
void myresume() {
synchronized(signal) {
suspendFlag = false;
signal.notify();
}
}
}
EDIT: Final code here and working !
run() {
try {
while(true){
synchronized(signal) {
while(suspendFlag) {
try {
signal.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
runOnUiThread(new Runnable() {
#Override
public void run() {
//....
}
}
});
Thread.sleep(2000);
i++;
}
}
}
}
signal.wait() is called from within the UI thread (I assume, runOnUIThread will execute the given Runnable on the UI thread). This will block/freeze the UI. Take it out of the run() method and put into the threads 'main loop'.
Rethink the main loop while (!suspendFlag)! This will abort the entire task instead of just suspending it.
Finally, make suspendFlag volatile to avoid visibility issues.
I'm trying to use threads to show a progress bar on the CLI in java while doing a long operation (generating md5sums for a batch of large files).
I've written a bit of code, and it works, but I'd like to know if I'm using threads correctly as I'm pretty new to this.
I have two class files, ProgressThreadTest.java and CountToABillion.java
CountToABillion.java:
public class CountToABillion implements Runnable {
double count = 0;
public void echoCount() {
System.out.println(count);
}
#Override
public void run() {
for (double x=0;x<1000000000;x++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count = x;
echoCount();
}
}
}
ProgressThreadTest.java:
public class ProgressThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread doCount=new Thread(new CountToABillion());
doCount.start();
}
}
It works as expected and counts upwards on the command line.
Anyone have any comments on whether or not this is a good way to do threads?
Also, because I am updating the progress in the counting loop, it will update every 10ms. How would I change the code to only output the count once every second?
Using javax.swing.Timer is probably the easier solution:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class CountToABillion implements Runnable {
double count = 0;
Timer progressTimer;
public void echoCount() {
System.out.println(count);
}
#Override
public void run() {
progressTimer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
echoCount();
}
});
progressTimer.setRepeats(true);
progressTimer.start();
for (double x=0;x<1000000000;x++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count = x;
}
progressTimer.stop();
}
}
Using java.util.concurrent.ScheduledThreadPoolExecutor is the better and more scalable solution:
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CountToABillion implements Runnable {
double count = 0;
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
public void echoCount() {
System.out.println(count);
}
#Override
public void run() {
Runnable task = new Runnable() {
public void run() {
echoCount();
}
};
exec.scheduleAtFixedRate(task, 1, 1, TimeUnit.SECONDS);
for (double x=0;x<1000000000;x++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count = x;
}
exec.shutdownNow();
}
}
Option 1:
int sleep = 10; //ms
int echo = 1000; //ms
for (double x=0;x<1000000000;x++) {
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count = x;
if((x*sleep % echo) == 0) {
echoCount();
}
}
Option 2:
Create a new Class to manage your counter, it should be able to add, reset and so on. You will have to make sure it's thread safe (writing new values in case you want to update from various threads).
Make one thread that increases the counter in given intervals
Make another thread that polls the current count in other given intervals and print.
long last=0;
#Override
public void run() {
for (double x=0;x<1000000000;x++) {
try {
doWork();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count = x;
if((System.currentTimeMillis()-last)>=1000) //post every second
{
last=System.currentTimeMillis();
echoCount();
}
}
}
This will print the count once every second assuming "work" does not take more than a second.
#Override
public void run() {
for (int i = 0; i < 1000000000; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
count = i;
if(i % 100 == 0) {
echoCount();
}
}
}
By using i % 100 == 0 you're checking if i is divisible by 100 without rest value. If that's the case, it means that you have ran 100 times 10ms which is 1000ms which is 1s. So you will output your echoCountt() every second.
This is an okay way to use threads. But your thread will keep running until it has counted to 10000000 seconds.
On a sidenote, you should use 'i' instead of 'x' in for loops. It's more widely used like this and will be easier to read for experienced java developers
I have got my custom widget that changes background when hover. It is working nice but I would like to have smooth transition between no background and hover background. It will work with GC.setAlpha(), but:
Display.getDefault().asyncExec(new Runnable() {
public void run() {
for (int i=0;i<255;i++) {
setBG(BGHelper(imgHover,i)); //i - alpha
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
This code wait until i == 255, but it doesn't display a smooth transition. Why?
This can not work, because as long as you are in your Code SWT will not repaint or change the component.
You should do the work in a separate Thread and call Display.asyncExec for every change.
for (int i = 0; i < 255; i++) {
final int x = i;
Display.getDefault().asyncExec(new Runnable() {
public void run() {
setBG(BGHelper(imgHover,x)); //x - alpha
}
});
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}