This is a bit weird, but I have no idea where the problem is.
In my onCreate() I have this code:
GameRunningNotesTimer().start();
and then out of onCreate I have this code:
Thread GameRunningNotesTimer = new Thread(new Runnable() {
public void run() {
int sleepingTime;
try {
if (r_settings.getGameOver() == 0) {
sleepingTime = 1000 - (r_settings.getInternalLevel() * 100);
if (r_settings.getInternalLevel() == 0) {
Thread.sleep(1000);
} else {
if (sleepingTime <= 399)
{
sleepingTime = 350;
}
Thread.sleep(sleepingTime);
}
if (r_settings.getGameOver() == 1){ gameOver(); }
myHandler2.sendEmptyMessage(0);
} // End of if (r_settings.getGameOver()
} catch (Exception e) { Log.e("MUSIC!!!!!", "Error in activity", e); }
}// End of run
}); // End of GameRunningNotesTimer()
final Handler myHandler2 = new Handler() {
#Override
public void handleMessage(Message msg) {
//text2.setText(""+item[0]);
int z = 1;
if (r_settings.getGameStarted() == true)
{
changeNoteFromTimer();
} else {
startingCountdown(z);
}
} // end of handleMessage()
};
but this GameRunningNotesTimer().start(); is underlined in red (in Eclipse) and when I mouseover it it says: The method GameRunningNotesTimer() is undefined for the type GameScr
What am I doing wrong? another thread/handler in the same class is not giving me this problem.
Thanks!
It should be GameRunningNotesTimer.start(); not GameRunningNotesTimer().start();
Related
Description:
In my app, I need to print data using Bluetooth printer.
The UI thread has to wait until the other thread dealing with printing
completes its task
The printing thread sets a value whether it is able to print or not
problem: The UI thread in the app is not waiting and its immediately getting the default status false
Where I am doing mistake in the following code?
UI thread:
private void printingStatus()
{
if(printData.isPrintFinished())
// do something
else
// do something
}
// PrintData class that executes printing in a different thread
private boolean printFinished = false;
// UI thread asks this method whether printing is success or failure
public boolean isPrintFinished() {
return printed;
}
public void setPrintFinished(boolean printed) {
this.printed = printed;
}
public static interface IPrintFinished {
public void onPrintFinished(boolean success);
}
public void printData() {
sendDataToPrinter(context, contentToPrint, new IPrintFinished() {
#Override
public void setPrintFinished(boolean success) {
if (success) {
setPrintFinished(true);
Logger.e("inside if success - printed"+printed);
}
setPrintFinished(false);
Logger.e("printed outside if" + printed);
}
});
}
public static void sendDataToPrinter(final Context context, final contentDefinition contentToPrint, final IPrintFinished listener) {
new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
// starts here the actual printing and gets a result
int tmpResult;
try {
DataPrinter.getInstance().print(contentToPrint);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Logger.e("exceptpion:" + e);
}
tmpResult = STATUS_PRINTED;
} catch (TechnicalException e) {
Logger.e("exceptpion:" + e);
if (e.getMessage() != null && DataPrinter.ERROR_BLUETOOH_IS_DISABLED.equals(e.getMessage()))
tmpResult = STATUS_BLUETOOTH_DISABLED;
else
tmpResult = STATUS_ERROR;
}
final int result = tmpResult;
Logger.e("print result:"+result);
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
if(result == STATUS_PRINTED) {
if (listener != null) {
Logger.e("inside the listener status printed");
listener.onPrintFinished(true);
}
} else if (result == STATUS_BLUETOOTH_DISABLED) {
SimpleToast.showToast("bluetooth disabled");
if (listener != null) {
listener.onPrintFinished(false);
}
} else {
SimpleToast.showToast("cannot connect to printer");
if (listener != null) {
listener.onPrintFinished(false);
}
}
}
});
Looper.loop();
}
}).start();
}
You cannot hold your UI thread for sometime. That will result in ANR state. Its the main thread which handles UI components.
I am implementing TTS (Text to Speech) support in my Android app. I am showing my code :
TextSpeech textSpeech = new TextSpeech();
textToSpeech = new TextToSpeech(this, textSpeech);
private class TextSpeech implements TextToSpeech.OnInitListener {
#Override
public void onInit(final int status) {
if (status != TextToSpeech.ERROR) {
if (TextToSpeech.LANG_AVAILABLE == textToSpeech.isLanguageAvailable(Locale.ENGLISH)) {
Thread thread = new Thread() {
#Override
public void run() {
super.run();
textToSpeech.setLanguage(Locale.ENGLISH);
try {
for (int i = 0; i < 10; i++) {
if (Util.isGreaterThanApi21()) {
textToSpeech.speak("" + i, TextToSpeech.QUEUE_FLUSH, null, null);
} else {
textToSpeech.speak("" + i, TextToSpeech.QUEUE_FLUSH, null);
}
Thread.sleep(1000);
}
} catch (Exception exception) {
}
}
};
thread.start();
} else {
Toast.makeText(ViewWorkplanActivity.this, "Language Not Supported", Toast.LENGTH_SHORT).show();
}
}
}
}
When I run this code, some devices missing 3-4 number or taking 3-4 seconds for initialization. Can any body tell me how can I remove this error?
I tried to implement a layout that works like a progress bar. I want to it to be able to be set to any level I want in special cases. For example to be set to 20.
#Override
public void handleMessage(Message msg) {
if (msg.what == 0x123) {
mCDrawable.setLevel(mProgress);
}
}
Runnable a= new Runnable() {
#Override
public void run() {
running = true;
handler.sendEmptyMessage(0x123);
mProgress = 20;
try {
Thread.sleep(18);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
public void add(int num){
Thread s = new Thread(a);
s.start();
}
I do it by calling the "add" function.
The problem is that in a "while" where the progress changes continueslly it works:
Runnable r = new Runnable() {
#Override
public void run() {
running = true;
while (running) {
handler.sendEmptyMessage(0x123);
if (mProgress > MAX_PROGRESS) {
mProgress = 0;
}
mProgress += 100;
try {
Thread.sleep(18);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
What is the difference? How can I set it to a specific value otherwise?
---edit----:
I tried this code and it still doesnt work:
public void add(int num){
int lvl = mClipDrawable.getLevel();
Log.d("______________", "the first was "+lvl);
lvl += 100;
if (lvl > 10000) {
lvl = 1000;
}
Log.d("______________", "set to "+lvl);
mClipDrawable.setLevel(lvl);
}
the first level was 0 and it set 100..
My code have more than one thread and Runnable. My problem is i change the value of a certain variable in the thread that the Runnable calling .
After the calling i make a check on that variable value but the value was not retrieved yet.
How can i retrieve the value after the processing? Here is the Runnable and the Thread code:
final Runnable r = new Runnable()
{
public void run()
{
if(flag==true)
onSwipe();
if(SwipeAgain==true)
handler.postDelayed(this, 1000);
}
};
private void onSwipe() {
new Thread() {
public void run() {
String data = null;
decryption_data = null;
encryption_data = null;
SwipeAgain=false;
handler.post(clear_encryption);
try {
data = sreader.ReadCard(15000);
} catch (Exception ex) {
if (ex instanceof TimeoutException) {
return;
} else
CloseSinWave();
}
if (data == null) {
SwipeAgain=true;
encryption_data = sreader.GetErrorString();
if (encryption_data.equalsIgnoreCase("cancel all"))
return;
handler.post(display_encryptiondata);
} else {
encryption_data = "\n" + data;
handler.post(display_encryptiondata);
}.start();
}
SwipeAgain is the value i want after processing
You have to use Callable, Runnable interface do not pass values to the parent method.
See this example.
You may require to use Generic Objects
Use a MONITOR final Object to wait and notify it when processing is done.
private final MONITOR Object[] = new Object[0];
private AtomicBoolean ready = new AtomicBoolean(false);
final Runnable r = new Runnable() {
public void run()
{
if(flag==true){
ready.set(false);
onSwipe();
synchronized(MONITOR){
if(!ready.get()){
try{
MONITOR.wait(); //will block until it get notified
}catch(InteruptedException e){}
}
}
}
if(SwipeAgain==true)
handler.postDelayed(this, 1000);
}
};
private void onSwipe() {
new Thread() {
public void run() {
try{
String data = null;
decryption_data = null;
encryption_data = null;
SwipeAgain=false;
handler.post(clear_encryption);
try {
data = sreader.ReadCard(15000);
} catch (Exception ex) {
if (ex instanceof TimeoutException) {
return;
} else
CloseSinWave();
}
if (data == null) {
SwipeAgain=true;
encryption_data = sreader.GetErrorString();
if (encryption_data.equalsIgnoreCase("cancel all"))
return;
handler.post(display_encryptiondata);
} else {
encryption_data = "\n" + data;
handler.post(display_encryptiondata);
}finally{
synchronized(MONITOR){
ready.set(true);
MONITOR.notifyAll(); //notify (and so unblock r.run())
}
}
}.start();
}
I have a ball that keeps moving from start. I want to stop ball on button click. When I clicked on button it show the Toast, but the ball keep on moving. It doesn't stop.
Please guide me how to stop ball on button click. My code for Activity is there.
#SuppressLint("HandlerLeak")
public class BounceActivity extends Activity {
private static final int GAME_START = 500;
private static final int GAME_STOP = 600;
Thread myRefreshThread = null;
BounceView myBounceView = null;
int width = 0;
int height = 0;
Handler myGUIUpdateHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case BounceActivity.GAME_START:
myBounceView.invalidate();
break;
case BounceActivity.GAME_STOP:
Log.d("BounceView", "Game state: " + BounceView.game_state);
Toast.makeText(BounceActivity.this, "Game stopped", Toast.LENGTH_SHORT).show();
myRefreshThread = null;
break;
}
super.handleMessage(msg);
}
};
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
this.myBounceView = new BounceView(this, dm.widthPixels, dm.heightPixels);
this.setContentView(myBounceView);
myRefreshThread = new Thread(new RefreshRunner());
myRefreshThread.start();
}
class RefreshRunner implements Runnable {
#Override
public void run() {
while (myRefreshThread != null) {
if(BounceView.game_state == 0) {
Message msg = Message.obtain();
msg.what = BounceActivity.GAME_START;
myGUIUpdateHandler.sendMessage(msg);
} else if (BounceView.game_state == 1) {
Message msg = Message.obtain();
msg.what = BounceActivity.GAME_STOP;
myGUIUpdateHandler.sendMessage(msg);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}}
You are accessing and setting myRefreshThread on different threads, which can be problematic.
Instead of checking if myRefreshThread is null in your while loop, you can add a "running" flag to RefreshRunner, and a stop method that sets it to false.
Than check that flag in the while loop.
Hold a reference to your RefreshRunner (the one you pass to myRefreshThread), and call stop() when you want the animation to stop.
class RefreshRunner implements Runnable {
private void mRunning = true;
public void stop () {
mRunning = false;
}
#Override
public void run() {
while (mRunning) {
if(BounceView.game_state == 0) {
Message msg = Message.obtain();
msg.what = BounceActivity.GAME_START;
myGUIUpdateHandler.sendMessage(msg);
} else if (BounceView.game_state == 1) {
Message msg = Message.obtain();
msg.what = BounceActivity.GAME_STOP;
myGUIUpdateHandler.sendMessage(msg);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}}