I am working on a Testing Project for me , just so I could learn more , so now I need to update the text of a TextView constantly every 250 milliseconds through a for(;;) loop , it happens after a Button click ... My problem is that whenever I press that button my app freezes (Yes my button is totally working , verified through previous testings) , I am using a handler to the Main thread doesn't get affected while the Runnable is up ... Here is my code of the Button and Handler ...
final Handler handler = new Handler();
B3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
for(;;){
String a = Shells.sendSingleCommand("free");//Here I send a command "free" and it returns its output
text.setText(a);//text is my TextView which is used through my experimentations ...
synchronized(this){
try{
wait(250);
}catch(Exception e){
}
}
}
}
});
}
});
If you need anymore info ask please :)
use handler.postDelayed for updating textview constantly every 250 milliseconds instead of using for loop to avoid freeze current Activity as :
Handler handler=new Handler();
B3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.post(runnable);
}
});
Runnable runnable=new Runnable(){
#Override
public void run() {
String a = Shells.sendSingleCommand("free");
text.setText(a);
handler.postDelayed(runnable, 250);
}
};
Android doesnt allow you to do long tasks in the main thread. If you need to do something like this I recommend moving the for loop and depdendent code into a separate thread..
Related
I have setup a stop watch using the com.apache.commons library and the stop watch seems to work fine. What I don't know how to do is display this stopwatch in a textView in my app. In general, I have no idea how that would work, i.e. How exactly would a stopwatch be displayed in a textView, given that the time on a stopwatch keeps changing constantly? At the moment, I have the code below and it updated the text in the textView every second for about 2 seconds and then I got a weird error. I'm not even sure if this is the right way to go about doing this. Please help!
Timer timer = new Timer();
TimerTask timerTask;
timerTask = new TimerTask() {
#Override
public void run() {
timeText.setText(time.toString());
}
};
timer.schedule(timerTask, 0, 1000);
The error I got after 2 seconds (and it successfully updated the time) was :
"only the original thread that created a view hierarchy can touch its views"
You can only update a TextView on the UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
//stuff that updates ui
}
});
Your code becomes
Timer timer = new Timer();
TimerTask timerTask;
timerTask = new TimerTask()
{
#Override
public void run()
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
timeText.setText(time.toString());
}
});
}
};
timer.schedule(timerTask, 0, 1000);
You may have to do myActivityObject.runOnUiThread() if you're getting an error there.
See this for more detail.
To update a view from another thread, you should use handler.
private void startTimerThread() {
Handler handler = new Handler();
Runnable runnable = new Runnable() {
private long startTime = System.currentTimeMillis();
public void run() {
//Change the condition for while loop depending on your program logic
while (true) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable(){
public void run() {
timeText.setText(time.toString());
}
});
}
}
};
new Thread(runnable).start();
}
So I have an activity which runs a simple snakes and ladders game, and I want to allow the player to click a button and move, which would subsequently be followed by the computer moving. My problem is, that once the player moves, the computer immediately makes its move.
Instead I want the activity to wait before the computer makes its move. I've looked around a lot and found that waiting involves using a thread, but I have failed to implement it without my app crashing
My attempt at declaring a thread:
final Runnable runnable = new Runnable() {
#Override
public void run()
{
while (true)
{
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
};
Thread thread= new Thread(runnable);
My onClick() method for the button:
Button rollButton = (Button) (findViewById(R.id.rollButton));
rollButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//executes only if current player is a human
if(GAME_BOARD.getCurrentPlayer().isHuman()) {
GAME_BOARD.rollDie(); // rolls the die
showDie(GAME_BOARD); // displays die on screen
GAME_BOARD.move(); // moves the player and sets next player as current player
playerTurn.setText(GAME_BOARD.getCurrentPlayer().getName() +"'s turn");// sets TextView to display who's player's turn it is
thread.start();
if(!GAME_BOARD.getCurrentPlayer().isHuman()) {
GAME_BOARD.rollDie();
showDie(GAME_BOARD);
GAME_BOARD.move();
playerTurn.setText(GAME_BOARD.getCurrentPlayer().getName() +"'s turn");
}
}
}
});
So again, my question is, how do I make it so that before the second if statement executes, the activity waits, say 4 seconds?
you can use an Handler.postDeleayed. You have to provide a Runnable to execut and the delay period in milliseconds. The Runnable will be executed on the UI Thread
You can use Handle to post your task defined in runnable after some delay
use this
Inside Activity define
Handler hand = new Handler();
and define your task in runnable like this
Runnable run = new Runnable() {
#Override
public void run() {
**your Task here.......**
}
};
In on click event
btnStartShow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
hand.postDelayed(run,3000); // For delay three seconds
}
});
also remove all pending messages by calling following sentence at appropriate place
hand.removeCallbacksAndMessages(null);
Use a CountDownTimer:
CountDownTimer timer = new CountDownTimer(4000, 1000) {
#Override
public void onFinish() {
*function containing the second statement*
}
#Override
public void onTick(long millisLeft) {
// not ticking
}
};
and in the onClick method in the click listener use:
timer.start();
Try the following,
rollButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Runnable runnable = new Runnable() {
#Override
public void run() {
// whatever you would like to implement when or after clicking rollButton
}
};
rollButton.postDelayed(runnable, 5000); //Delay for 5 seconds to show the result
}
My problem is...
I have 2 events.. onCreate and Onclick. I have a thread running inside onCreate and i have to stop it inside onClick. Is this possible?
If yes, please provide me with some hints/ code snippets how to implement this.
My code inside onCreate event is this:-
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen);
button = (Button) findViewById(R.id.btn);
button.setOnClickListener(this);
try{
bright = Settings.System.getInt(getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS);
}catch(Exception ex){
ex.printStackTrace();
bright = 1.0f;
}
lp = getWindow().getAttributes();
new Thread(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(10000);
mHandler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
lp.screenBrightness= dim;
getWindow().setAttributes(lp);
// SLEEP 2 SECONDS HERE ...
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
lp.screenBrightness=bright;
getWindow().setAttributes(lp);
}
});
}
}, 2000);
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
}
this activity is running inside a loop. And i want to stop this wen i click on the button. It seems that i cannot call the Thread.interrupt() method inside the button onclick event. How do i proceed with this?
Declare an boolean mRunnning in your class, this is like a flag, and custom running thread will depend on this to know if it has been cancelled.
As usual, you have a loop in your thread, instead of while(true) do while(mRunning).
Also, you are making your thread sleep, during sleep, thread won't be able to check on mRunning variable, you will have to call interrupt() on thread object to make it stop.
It will be better to use a variable to hold thread reference Thread t = new Thread(....
So, now to stop your thread you have to call mRunning = false and then t.interrupt().
according to your current situation based on previous answer comment . you r trying like:
myThread = new Thread(new Runnable
right?
then u should also delete .start(); part of your previous coding. then write:
myThread.start();
u should declare myThread as global in your class, so that u can access this thread from anywhere in your class. now u can stop thread in onClick
u should combine this answer and User117 s answer together .
If you create a reference you can access it from everywhere in you class. So, in the class body ad something like
Thread thrd
Just like you would do so with a Button, TextView, or whatever. Then in the onCreate method add the reference like
thrd = new Thread(new Runnable(){
Now you have a reference to your thread you can use everywhere in your class.
instead of
while(true)
inside the run() Method, declare a boolean variable to true and change it after onClick. For example:
private boolean shouldRun = true;
then in the run() method:
#Override
public void run() {
// TODO Auto-generated method stub
while (shouldRun==true) {
.
.
.
and in your onClick:
#override
public void OnClick(View v){
shouldRun=false;
.
.
.
I am trying to play an mp3 file (with an onClickListener) and stop after 2 seconds. I tried the code below but it is not working. Could anyone please help?
final MediaPlayer mpsound = MediaPlayer.create(this, R.raw.media_player_sound);
ImageView sound = (ImageView) findViewById(R.id.button);
sound.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mpsound.start();{
sleep(2000);
mpsound.stop();
}
}
});
Why are you calling stop() on mpfrog if you are playing audio with mpsound? You need to call the stop() function on the mpsound MediaPlayer. Also, you might want to add the #Override annotation to your onClick() method.
for the override...
sound.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mpsound.start();{
sleep(2000);
mpsound.stop();
}
}
});
for a timer.....
Handler handler = new Handler(){
#Override
public void handleMessage(Message msg){
mpsound.stop();
}
};
//Task for timer to execute when time expires
class SleepTask extends TimerTask {
#Override
public void run(){
handler.sendEmptyMessage(0);
}
}
//then in some other function...
Timer timer = new Timer("timer",true);
timer.schedule(new SleepTask(),2000);
You have to wait 2 seconds in different thread, for this case use your own created thread and wait there and stop player, or you can use CountDownTimer - very simple solution.
You can find same question aggregated here and here
In eclipse you can use autocomplete (ctrl + space by default) to fill automatically all inmplemented methods and #Overrides will already be there.
I have to display some data after every 10 seconds. Can anyone tell me how to do that?
There is an another way also that you can use to update the UI on specific time interval. Above two options are correct but depends on the situation you can use alternate ways to update the UI on specific time interval.
First declare one global varialbe for Handler to update the UI control from Thread, like below
Handler mHandler = new Handler();
Now create one Thread and use while loop to periodically perform the task using the sleep method of the thread.
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(10000);
mHandler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
// Write your code here to update the UI.
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
Probably the simplest thing to do is this:
while(needToDisplayData)
{
displayData(); // display the data
Thread.sleep(10000); // sleep for 10 seconds
}
Alternately you can use a Timer:
int delay = 1000; // delay for 1 sec.
int period = 10000; // repeat every 10 sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
displayData(); // display the data
}
}, delay, period);
Andrahu was on the right track with defining a handler. If you have a handler that calls your update functions you can simply delay the message sent to the handler for 10 seconds.
In this way you don't need to start your own thread or something like that that will lead to strange errors, debugging and maintenance problems.
Just call:
Handler myHandler = new MyUpdateHandler(GUI to refresh); <- You need to define a own handler that simply calls a update function on your gui.
myHandler.sendMessageDelayed(message, 10000);
Now your handleMessage function will be called after 10 seconds. You could just send another message in your update function causing the whole cycle to run over and over
There is Also Another way by Using Handler
final int intervalTime = 10000; // 10 sec
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Display Data here
}
}, intervalTime);
There is a Simple way to display some data after every 10 seconds.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
ActionStartsHere();
}
public void ActionStartsHere() {
againStartGPSAndSendFile();
}
public void againStartGPSAndSendFile() {
new CountDownTimer(11000,10000) {
#Override
public void onTick(long millisUntilFinished) {
// Display Data by Every Ten Second
}
#Override
public void onFinish() {
ActionStartsHere();
}
}.start();
}
Every 10 seconds automatically refreshed your app screen or activity refreshed
create inside onCreate() method i tried this code will work for me
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
//CALL ANY METHOD OR ANY URL OR FUNCTION or any view
}
});
}
} catch (InterruptedException e) {
}
}
};t.start();