Drawing in a bitmap sometimes gets screwedup - java

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

Related

Needing JAVA help in animation

I'm new in Java (still learning) all the other works have gone well but only this animation gives my headache and the coffee won't even help=(!
I should make an animation of Javaman (10 gif pictures named as T1, T2,...T10) I should use Thread, MediaTracker-class and addImage-method. Then I should specify the speed of the animation by using sleep-method (I used join-method if that's right??).
(MY JAVA CODE GOES LIKE THIS)
import java.applet.Applet;
import java.awt.*;
public class Animaatio extends Applet implements Runnable {
Image[] images = null;
MediaTracker tracker = null;
int current = 0;
Thread animThread;
#Override
public void init() {
// Creating a new media tracker, to track loading images
tracker = new MediaTracker(this);
// Creating an array of ten images
images = new Image[10];
// Downloading the images
for (int i = 0; i < 10; i++) {
// Loading the images
images[i] = getImage(getCodeBase(), (i + 1) + "T.gif");
tracker.addImage(images[i], 0);
}
try {
tracker.waitForAll();
} catch (InterruptedException e) {
}
}
#Override
public void start() {
if (animThread == null) {
animThread = new Thread(this);
animThread.start();
}
try {
animThread.join();
} catch (InterruptedException e) {
}
}
#Override
public void paint(Graphics g) {
g.drawImage(images[current++], 0, 0, this);
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
}
}
The problem is that I don't see any animation just an empty applet viewer which just keeps running. Problem might be caused if the images are storaged in the wrong place? If someone could wreally help me, I would be really thankful for my knight=).

Do stuff inside a `for` in a Thread

#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();

repaint() in Thread is making a high usage CPU

I'm using a Thread to scroll text in my application :
public void run() {
super.run();
while (!isInterrupted()) {
if (X >= -getPreferredSize().getWidth()) {
X -= 2;
} else {
decrementMessagesInList(getMessages());
addMessage(getMessages());
prepare();
X = getParentWidth();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
repaint();
}
}
However, see that with sleep my CPU usage is very high, I need to reduce that. Can anyone suggest how to do it ?
If I can make the assumption that your code only needs to scroll the text in response to some event (say a click or drag or something) then you should make your thread go into a wait state then have the code that triggers the update post a notification over to the thread which will then wake up and do the update. Something like this:
Object syncObj = new Object();
public void run() {
while (true) {
try {
syncObj.wait();
if (X >= -getPreferredSize().getWidth()) {
X -= 2;
} else {
decrementMessagesInList(getMessages());
addMessage(getMessages());
prepare();
X = getParentWidth();
}
repaint();
} catch (InterruptedException ie) {
// handle the exception
}
}
}
Then in the code which handles/generates the event that causes a need to scroll
public void onClick(..) {
syncObj.notifyAll();
}
You also need to guard against spurious wake ups of your thread to make sure the event you were waiting for actually happened. See Do spurious wakeups actually happen?.

Thread runOnUiThread pausing/resume after notify() not continue

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.

display.async and smooth transitions

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();
}
}

Categories