Why do I need a Handler object in this example? - android

public class ProgressBarTest extends Activity {
private int progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress_bar);
final Handler handler = new Handler();
progress = 0;
final ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
new Thread(new Runnable() {
public void run() {
while (progress < 10) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
progress++;
}
handler.post(new Runnable() {
#Override
public void run() {
pb.setVisibility(View.GONE);
}
});
}
}).start();
}
}
Why can't I just put the pb.setVisibility(View.GONE) in the first Runnable inner class? Like this: The program crashes if I write it this way.
new Thread(new Runnable() {
public void run() {
while (progress < 10) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
progress++;
pb.setVisibility(View.GONE);
}
}
}
The program crashes when the setVisibility statement is executed.

You cannot update ui from a thread. Ui should be updated on the ui thread.
In the second one you are setting the visibility of progressbar inside the threads runs method. Hence it crashes. So you use handler to set the visibility of progress bar in the the first
To know more about handlers.
http://developer.android.com/reference/android/os/Handler.html

Related

How to make a thread repeat in Android

I try to implement a thread that runs next to the main thread, this thread isexecuted in 20 seconds, I need that after finishing the thread again it executes again in a continuous way.
With this code the thread is executed once, but how do I do it to run again?
public class MainActivity extends AppCompatActivity {
.
.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
.
.
treadTimer();
}
private void treadTimer(){
new Thread(new Runnable() {
#Override
public void run() {
for(int i=1; i<= 20; i++){
UnSegundo();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getBaseContext(), "Tarea Larga Finalizada", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
private void UnSegundo(){
try{
Thread.sleep(1000);
}catch (InterruptedException e){}
}
}
This is one of the ways
Handler handler = new Handler();
private Runnable runnable = new Runnable() {
#override
public void run() {
doYourThing();
handler.post(this, 20000);
}
}
handler.post(runnable);

Should I pause my thread or not Android

So I have thread where it checks every 10ms's if drag is almost outside draggingzone. Basicly my thread code is doing nothing 99% of time so should I make it to pause and resume only when needed? Or does this literally do nothing when right and left are false?
My code looks like this
timer = new Thread() { //new thread
public void run() {
b = true;
try {
do {
sleep(10);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (right) {
dragzone.moveleft(-5);
} else if (left) {
dragzone.moveleft(5);
}
}
});
}
while (b);
} catch (InterruptedException e) {
}
}
;
};
timer.start();
It looks like using a Thread here is not necessary, and you should switch to using a Handler and postDelayed()
First, declare your Handler, boolean, and a Runnable as instance variables:
Handler handler;
boolean b;
Runnable checkDragZone = new Runnable(){
#Override
public void run() {
if (right) {
dragzone.moveleft(-5);
} else if (left) {
dragzone.moveleft(5);
}
if (b){
handler.postDelayed(this, 10);
}
}
};
To start monitoring, set b to true, and start the Runnable:
handler = new Handler();
b = true;
handler.postDelayed(checkDragZone, 10);
To stop it (temporarily or permanently), just set b to false:
b = false;
It's not really a good practice to keep it running. You can start it when you detect the Drag action and then release it when it's finished.
Runnable runnable;
Thread globalThread;
public void startThread() {
if (threadController) {
runnable = new Runnable() {
#Override
public void run() {
while (threadController) {
for (int i = 0; i < adapter.getCount(); i++) {
final int value = i;
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
viewPager.setCurrentItem(value, true);
}
});
}
}
}
};
globalThread = new Thread(runnable);
globalThread.start();
} else {
return;
}
}
#Override
public void onPause() {
super.onPause();
threadController = false;
handler.removeCallbacks(runnable);
runnable = null;
if (globalThread != null) {
globalThread.interrupt();
}
}
#Override
public void onDestroy() {
super.onDestroy();
threadController = false;
}
Your resolve must be like this globalThread.interrupt();

Spinner Progressbar in android

I want to implement ProgressBar in Android and when I execute the program, Progressbar should show for up to 2 seconds. I can't get it to work properly but I can't figure out why.
public void myThread(){
Thread th=new Thread(){
#Override
public void run(){
try
{
while(mRunning)
{
Thread.sleep(10L);//10s wait
YourCurrentActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
//DISMISS PROGRESS BAR HERE
mRunning=false;
}
});
}
}catch (InterruptedException e) {
// TODO: handle exception
}
}
};
th.start();
}
I have tried this but it does not giving me output as i want.
That what handlers are for in Android.
Example:
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
// cancel or dismiss your progressbar
}
}, 2000);

why thread creation is failed?

I want to turn on/off the flash light in infinite loop, so when it turned on it should wait for 5 seconds and then turned off then wait 5 seconds to turned on again, and so on...
how I can do that?
here is my code:
b2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// num = Integer.parseInt(n.getText().toString());
while(bl){
if(camera == null){
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
turnOn();
}
});
}
}).start();
}
else{
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
turnOff();
}
});
}
}).start();
}
}
}
});
I would recommend not using Threads in order to achieve this. Why not use the Runnable class and post it with a delay via a Handler? For example:
Handler handler = new Handler(); // make this a member variable of your class
boolean isOn = false; // make this a member variable of your class
final Runnable flashRunnable = new Runnable() {
#Override
public void run() {
if (isOn) {
turnOff();
isOn = false;
} else {
turnOn();
isOn = true;
}
handler.postDelayed(flashRunnable, 5000);
}
};
handler.postDelayed(flashRunnable, 5000);
If you need to run the code inside the Runnable on the UI thread, you even call postDelayed on a View instead of creating a Handler
Try something like so, using Executors instead of (ugly) Thread.sleep():
boolean cameraOn = true
final Runnable runnable = new Runnable() {
#Override
public void run() {
// your logic here:
// if (cameraOn) ...
// else ...
// cameraOn = !cameraOn
}
};
Executors.newScheduledThreadPool(1).schedule(new Runnable() {
#Override
public void run() {
runnable.run();
}
}, 5, TimeUnit.SECONDS);

Splash Screen not working with Thread

I write a Splash Screeen to run at the boot time of application
public class SplashScreen extends Activity {
ImageView imgView;
int[] imgID = new int[]{R.drawable.frame0, R.drawable.frame1, R.drawable.frame2, R.drawable.frame3,
R.drawable.frame4, R.drawable.frame5, R.drawable.frame6};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
imgView = (ImageView) findViewById(R.id.imgSplash);
new Thread(new WelcomeScreen()).start();
}
private class WelcomeScreen implements Runnable {
#Override
public void run() {
try {
for (int i = 0; i < imgID.length; i++)
{
imgView.setImageResource(imgID[i]);
sleep(500);
}
} catch (InterruptedException e) {
}finally {
Intent intent = new Intent(SplashScreen.this,LoginActivity.class);
startActivity(intent);
finish();
}
}
}
}
It getting error "Sorry the application has stopped unexpectedly" . I don't know why . Somebody can help me ????
you can not set the resource for yuor ImageView inside a thread different from the UI Thread.
you can use runOnUiThread. It takes as paramter a runnable, and post it in the UI Thread queue. There, the UI thead takes it and update your ImageView. All in all your runnable will become:
private class WelcomeScreen implements Runnable {
#Override
public void run() {
try {
for (int i = 0; i < imgID.length; i++)
{
final int resuorceId = imgID[i];
runOnUiThread(new Runnable() {
#Override
public void run() {
imgView.setImageResource(resuorceId);
}
});
sleep(500);
}
} catch (InterruptedException e) {
}finally {
Intent intent = new Intent(SplashScreen.this,LoginActivity.class);
startActivity(intent);
finish();
}
}
You can not access your views from Thread.
You will need to put your code imgView.setImageResource(imgID[i]); in runOnUiThread
use like:
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
imgView.setImageResource(imgID[i]);
}
});
Thanks
You can not change something in UI from non-UI thread so replace this you code:
imgView.setImageResource(imgID[i]);
to:
runOnUiThread(new Runnable() {
#Override
public void run() {
imgView.setImageResource(imgID[i]);
}
});
//try code this way...
public class SplashScreen extends Activity {
private Intent launchIntent;
private Thread splashThread; //used for perform splash screen operation
private int splashTime = 10000, sleepTime = 50; //used for threading operation
private boolean active = true; //used for touch event
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splashscreen); //Set splashscreen.xml here
try {
splashThread = new Thread() { // Creating Thread for splash the screen
#Override
public void run() { // run method implemented to perform threading operation
try {
int waitTime = 0; //counter for threading
do {
sleep(sleepTime); //delay for specific time
if (active)
waitTime += 100;
//write your image code here that display your no. of images
} while (active && (waitTime < splashTime)); //Check touch condition and counter
} catch (Exception e) {
// to handle runtime error of run method
Validation.displayToastMessage(SplashScreen.this, e.toString()); //Call static method of class ToastMessage
}
finish(); //finish current activity
startJustCoupleActivityScreen(); //Call below defined function
}
};
splashThread.start(); //start thread here
} catch (Exception e) {
message("SplashScreen : "+ e.toString()); //Call static method of class ToastMessage
}
}
public void startJustCoupleActivityScreen() {
launchIntent=new Intent(SplashScreen.this,JustCoupleActivity.class); //call Next Screen
startActivity(launchIntent); //start new activity
}
#Override
public boolean onTouchEvent(MotionEvent event) { //onTouch Event
//on touch it immediate skip splash screen
if(event.getAction()==MotionEvent.ACTION_DOWN) active=false; //Check Touch happened or not
return true;
}
public void message(String msg)
{
Validation.displayToastMessage(SplashScreen.this, msg); //display Error Message
}
}

Categories

Resources