button.setText() and Thread.sleep() - android

Noob question on its way. In the code below I update text of a button in Android. Then I want to wait two seconds and then update the text again. If I comment the second b.setText("Send data"), the one after the sleep - then b.setText("Success") is written to the button. If I do not comment that one I will never see text "Success" on the button, only "Send data". It's like the Thread.sleep() is skipped when I have the second b.setText("Send data"). Google suggested to add a timer after setText("Success") so that setText() code would have time to be execited before the sleep. Did not help.
final Button b = (Button) findViewById(R.id.button);
b.setText("Send data");
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
b.setClickable(false);
b.setText("Success");
System.out.println("Debug before");
try
{
Thread.sleep(2000);
}
catch (Exception e)
{
}
System.out.println("Debug after");
b.setText("Send data");
b.setClickable(true);
}
});

Don't block your main thread. Use Handler.post instead
b.setClickable(false);
b.setText("Success");
System.out.println("Debug before");
new Handler().postDelayed(new Runnable(){
System.out.println("Debug after");
b.setText("Send data");
b.setClickable(true);
}, 2000);

There are many ways to do it.
you can run a new thread and then update view.
Or :
CountDownTimer countDownTimer = new CountDownTimer(2000, 1000) {
public void onTick(long millisUntilFinished) {
//
}
public void onFinish() {
//update your view
System.out.println("Debug after");
b.setText("Send data");
}
};
countDownTimer.start();

Related

Intent with Countdown crashes android app

My Android app crashes when it reaches countdown 0. Below is the part of code related to it.
final CountDownTimer countdown=new CountDownTimer(60000, 1000){
public void onTick(long millisUntilFinished)
{
tvTime.setText((millisUntilFinished / 1000)+"'s");
}
public void onFinish()
{
try{
tvTime.setText("Time Over");
this.cancel();
Toast.makeText(getApplicationContext(),"Answer: "+ OriginalWord, Toast.LENGTH_LONG).show();
Intent i=new Intent(LastJumble.this,ScoreCard.class);
i.putExtra("username",username);
i.putExtra("totalQues", totalQues);
i.putExtra("count", count);
startActivity(i);
}
catch (Exception e) {
// TODO: handle exception
}
}
}.start();
this.cancel() will try to cancel the CountDownTimer. Since the timer is finished this will break. If you mean to call a cancel method in your outer class you should reference it as OuterClass.this.cancel() where OuterClass is the name of the class.

Android Create an activity with no buttons

I am very confused as to why I cannot get this to work. I want to have a screen with no buttons run for 5 seconds while I do some things in the background, then navigate back to another screen. Is this not possible?
I have tried to put the code to run the background items in onCreate, onStart, and onResume, and all of these methods are fired before the screen actually displays. Is there another way to do this?
Edit The most recent version of my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync);
}
protected void onResume(){
super.onResume();
commitSync();
}
private void commitSync(){
TextView monthDayYear = (TextView)findViewById(R.id.month_day_year);
TextView hourMinuteSecond = (TextView)findViewById(R.id.hour_minute_second);
_application = (App)getApplicationContext();
try {
CountDownLatch latch = new CountDownLatch(1);
latch.await(5, TimeUnit.SECONDS);
//Ensure that we have flash
if(getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
Camera androidCamera = Camera.open();
Camera.Parameters p = androidCamera.getParameters();
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
androidCamera.setParameters(p);
//Flash and then turn off
androidCamera.startPreview();
latch.await(50, TimeUnit.MILLISECONDS);
androidCamera.stopPreview();
//Flash screen white
//Get date and time
Module syncModule = _application.getModule();
syncModule.start();
Calendar syncTime = syncModule.getDateAndTime();
//http://stackoverflow.com/questions/21988004/get-time-in-hhmmss-from-seconds-in-java
monthDayYear.setText(new SimpleDateFormat("MM/dd/yyyy").format(syncTime.getTime()));
hourMinuteSecond.setText(new SimpleDateFormat("HH:mm:ss:00").format(syncTime.getTime()));
//Navigate back to MainActivity
Intent mainActivityIntent = new Intent(SyncActivity.this, MainActivity.class);
startActivityForResult(mainActivityIntent, 1);
} else {
throw new Exception("Cannot access Android Flash");
}
} catch (Exception ex) {
Util.appendLog("Exception occured in Sync: " + ex.getMessage());
}
}
Maybe this help you:
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run() {
// Do some work like:
finish();
}
}, 500);
This run a code after some delay and you can put this code in your desired screen.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//The code you want to execute
}
}, timeUntilExecution);
This code should execute that run() method after the timeUntilExecution variable (in milliseconds) you could use this to execute what you want to do after the delay. Hope this helps.

How to show a counter in android UI

Can I use a thread for increment a counter and shows it in a frame of Android activity.
Public class MainActivity extendsActivity {
TextView counter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
counter = (TextView) findViewById(R.id.TV_counter);
Thread t = new Thread() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
for (int i = 0; i < 5; i++) {
try {
counter.setText("" + i);
System.out.println("Value of i= " + i);
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
};
t.start();
}
}
I wrote this code, but it run properly in console, but the text view displays i=4 in the terminal, I modified the time to sleep(3000) and the problem persists.
First you don't ever want to put sleep in UI Thread that can lead to unresponsive user interface and that is never good. You should use it just to update your graphics. Try replacing your code with this
Thread t = new Thread() {
public void run() {
for (int i = 0; i < 5; i++) {
try {
final int a = i;
runOnUiThread(new Runnable() {
public void run() {
counter.setText("" + a);
}
});
System.out.println("Value of i= " + i);
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
You are going to notice that sleep and for loop is outside UIThread and in your first thread, so basically all of your math is done outside and you just display the results.
This is just a correction of your code and suggestion for further thinking
EDIT: And for you to better understand why your code is not working, you set some value on your TextView, and immediately after you set UIThread to sleep, UIThread blocks instead of giving it time to finish updating graphics, after he finish sleep you set new value, and he never got to update previous one so in the end you see just the last one.
Hope this helps and enjoy your work.
you can use a CountDownTimer, and update your UI in the onTick() method ( this method is executed on the UI Thread):
int i=0;
CountDownTimer timer = new CountDownTimer(5000,1000) {
#Override
public void onTick(long millisUntilFinished) {
// this method will be executed every second ( 1000 ms : the second parameter in the CountDownTimer constructor)
i++;
txt.setText(i);
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
}
};
timer.start();

Button syncronized with thread android

How create a button which pause the thread which is inside the loop and another button which
resumes.
Runnable myRun = new Runnable(){
public void run(){
for(int j =0 ;j<=words.length;j++){
synchronized(this){
try {
wait(sleepTime);
bt.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}});
bt2.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
notify();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} }
runOnUiThread(new Runnable(){
public void run(){
try {
et.setText(words[i]);
i++;
} catch (Exception e) {
e.printStackTrace();
}
}});
}}};
doing some stuff say words.lenght=1000 times
then suppose user want to take break in between
click pause button with id = bt this button pauses thread until and user
clicks resume with id= bt1
Below is a hint , i think you can use for your problem. Its copied from the link i pasted at end.
A wait can be "woken up" by another process calling notify on the monitor which is being waited on whereas a sleep cannot. Also a wait (and notify) must happen in a block synchronized on the monitor object whereas sleep does not:
Object mon = ...;
synchronized (mon) {
mon.wait();
}
At this point the currently executing thread waits and releases the monitor. Another thread may do
synchronized (mon) { mon.notify(); }(On the same mon object) and the first thread (assuming it is the only thread waiting on the monitor) will wake up.
Check Difference between wait() and sleep()
You do it like this:
How to indefinitely pause a thread in Java and later resume it?
Only you call the suspend() and other methods from your buttons' OnClickListeners

Android timer with do while

My code is crashing and I need some help. Everything is running fine except for this part.
There is no errors but it crashes at timer.schedule(loadImg2, 5000); that is before the if (!c.moveToNext())
My question: am I using the timer correctly in the loop? Because that is where the code crashes.
I never see this log "+-+-+-+-+-+-+-+-+- Getting out " or anything that comes after.
do
{
Log.v("log_tag", "+-+-+-+-+-+-+-+-+- Ttrying to cancel ");
//timer.cancel();
Log.v("log_tag", "+-+-+-+-+-+-+-+-+- Timer canceled ");
timer = new Timer();
Log.v("log_tag", "+-+-+-+-+-+-+-+-+- New timer created ");
//delay amount of time(5s here) in milliseconds before first execution.
//period amount of time(1s here) in milliseconds between subsequent executions.
timer.schedule(loadImg2, 5000); //this did not produce any effect so far
if (!c.moveToNext())
{
//destroy
timer.cancel();
myImageView.setImageBitmap(null);
Log.v("log_tag", "+-+-+-+-+-+-+-+-+- Getting out ");
//get out of the loop or set c.moveToFirst()
break;
}
} while (true);
TimerTask loadImg2 = new TimerTask()
{
#Override
//Load Img2
public void run()
{
runOnUiThread(new Runnable()
{
public void run()
{
Log.v("log_tag", "+-+-+-+-+-+-+-+-+- Inside loadImg2 ");
titleText.setText(DisplayTitle(c));
Bitmap bitmap2 = BitmapFactory.decodeFile(c.getString(5));
myImageView = (ImageView) findViewById(R.id.imageview1);
myImageView.setImageBitmap(null);
timer.cancel();
}
});
}
}
There is a problem that you can't set timer.schedule() more than once time.
Try to catch an exception:
try{
timer.schedule(loadImg2, 5000);
} catch (IllegalArgumentException e){
Log.v(TAG, "IllegalArgumentException");
} catch (IllegalStateException e){
Log.v(TAG, "IllegalStateException");
}
Then the application doesn't crash. But the timer will set just in the first time.
I don't know the solution of this problem. I am trying to find it too.

Categories

Resources