I have this code for changing the screen color.
But I don't know how to stop this thread:
lin = (LinearLayout)findViewById(R.id.mainlayout);
new Thread(new Runnable() {
public void run() {
while (finalStatus < 1) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
colorHandler.post(new Runnable() {
public void run() {
if(flag)
{
lin.setBackgroundColor(Color.BLUE);
flag = false;
}
else
{
lin.setBackgroundColor(Color.RED);
flag = true;
}
}
});
}
}
}).start();
I tried to put:
Button btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(getBaseContext(),"STOP",Toast.LENGTH_SHORT).show();
finalStatus=1;
lin.setBackgroundColor(Color.BLACK);
}
});
and the thread stopped, but the screen is red, or blue, I need black.
Moreover, how to start this thread after I have stopped it?
I'm not sure what's the scenario for getting a background blue or red but let's assume it's when you set the finalStatus to 1. In order to avoid changing the background and still exiting the thread you can set it to a different value in your button click listener, let's say to 111. Adding the following condition before colorHandler.post will solve the issue:
if (finalStatus == 111) {
return;
}
Just put that lin.setBackgroundColor(Color.BLACK); code after the While loop in the outer thread run() method. and dont forget to use the handler for the same since other than UI thread wont update the UI.
Related
I want my button to work when I click it once. However, it only works if I click it twice.
I think this problem is related with Jsoup or Thread because when I removed the Jsoup method, it worked properly.
Of course, I have added Jsoup Library.
Here is my code:
View.OnClickListener listener = new View.OnClickListener(){
#Override
public void onClick(View v) {
new Thread(){
public void run(){
String word = editText.getText().toString();
try {
doc = Jsoup.connect("https://endic.naver.com/search.nhn?sLn=kr&searchOption=all&query="+word).get();
} catch (IOException e) {
}
Elements el = doc.getElementsByClass("fnt_e30");
if(el.size() == 0){
s="There is no result.";
return;
}
s="OK";
}
}.start();
textView.setText(s);
}
};
btn_search.setOnClickListener(listener);
I'm guessing that by 'works' you mean to say that the TextView get's set with the text "OK". In which case, your code is running properly, you have the s="OK"; running on a separate thread. Only after that value get's set will textView.setText(s); run as you expect it to. You'll probably want to do something along the following lines instead.
View.OnClickListener listener = new View.OnClickListener(){
#Override
public void onClick(View v) {
new Thread(){
public void run(){
String word = editText.getText().toString();
try {
doc = Jsoup.connect("https://endic.naver.com/search.nhn?sLn=kr&searchOption=all&query="+word).get();
} catch (IOException e) {
}
Elements el = doc.getElementsByClass("fnt_e30");
if(el.size() == 0){
s="There is no result.";
return;
}
s="OK";
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(s);
}
});
}
}.start();
}
};
btn_search.setOnClickListener(listener);
P.S - As mentioned by ADM in the comments, it's an asynchronous call (since it's done on a thread), Jsoup.connect will take time to connect and get the doc. You should preferably deactivate the button after it's clicked once (basically indicate to the user that the request is being handled and ask them to wait for the result).
You are doing it on wrong way. You are listening response and set in variable as well but not setting into the textview.
Why its happening second time? When you click first time code of setText will be executed but that will not having any value.
Right Approach. Add this code after you setting in value in s variable.
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(s);
}
});
I have a textview which i want to change with a thread and do it again and again (Like a digital clock). But i'm having problems with setting time between 2 changes. Here, the code:
display1 = (TextView) findViewById(R.id.textView1);
Thread timer2 = new Thread(){
#Override
public void run() {
synchronized (this){
runOnUiThread(new Runnable() {
#Override
public void run() {
int i = 0;
display1.setText("" + i);
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
display1.setText("" + (i+1));
}
});
}
}
};
timer2.start();
This sleep(2000); function makes textview invisible for the given time but i want it stand still till the next change. How can i do that?
But i'm having problems with setting time between 2 changes
Do NOT do sleep() on your UI thread. If you want to chain some actions with the delay, split your code into two runnables and the first one should set display1 and then post second runnable with the delay using postDelayed()
EDIT
want one of them to increase 3 per sec, and the other 5 per sec until they reach 1000 for instance
You can make your Runnable post itself until some criteria are met (i.e. time, counter value etc). Just at the end your Runnable check your conditions and if not met, call postDelayed(this, delay); and you are good.
You should use a Handler instead and dispatch your changes to the UI thread.
Handler mHandler = new Handler();
mHandler.post(new Runnable() {
#Override
public void run() {
// Code to be run right away
}
});
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
// Code to be run after 2 seconds
}
}, 2000);
Maybe split up what you need to do into separate methods. Here you have a UI method and a sleep method split up. Hope it helps
private void myMethod() {
new Thread() {
#Override
public void run() {
int i = 0;
doWorkOnUI(String.valueOf(i));
pause(2000);
doWorkOnUI(String.valueOf(i++));
}
}.start();
}
private void pause(int pauseTime) {
try {
Thread.sleep(pauseTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doWorkOnUI(final String string) {
runOnUiThread(new Runnable() {
#Override
public void run() {
display1.setText(string);
}
});
}
I want to add and clear window flag inside a thread but not working. Basically i want my thread to keep the screen on for two seconds and then clear the screen on flag.
Here's my code:
public class WriteCommThread extends Thread {
private long time=2000;
public WriteCommThread(float count) {
time = (long) count;
}
public void run() {
while(connectionUnAbort==true){
// Lock screen
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
slleep();
//Unlock screen
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
connectionUnAbort=false;
}
}
public void slleep(){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I solved it after doing research, i am posting the referred link.
Answer Link
Here's my solution to my problem and it worked perfectly. I added these runnable classes in my background thread (run method). And after sleeping i could clear the flag to keep the screen on.
runOnUiThread(new Runnable() {
public void run() {
//stuff that updates ui
MainActivity.this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
runOnUiThread(new Runnable() {
public void run() {
//stuff that updates ui
MainActivity.this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
I am using handler.postDelayed method to create some delay for some animation stuff.
With that i am playing some song as well using Mediaplayer. User can exit this action class by clicking next. But on next screen the same song is continuing even though i called stop method in the next button's onclicklistener.
Is it due to the timedelay that is added which gets executed after the next activity is loaded. Any idea?
handler.postDelayed(new Runnable() {
public void run() {
mp = MediaPlayer.create(getApplicationContext(), R.raw.num2);
mp.start();
imageView1.setImageResource(R.drawable.countcat2);
}
}, 2000);
Did you add a Log to see if run() gets called? I would assume that your handler gets unregistered; after all, postDelayed will wait until the looper kicks in again.
I assume your animation is faster than those 2000ms? You wouldn't be able to have your handler called anyway after your activity is gone, it's accessing imageView1 which I presume is destroyed in onDestroy.
You could consider adding a flag that will force the operation to be called immediately in onDestroy, and/or you could use a Timer. In case of the timer, be sure to not use something like imageView1 after it has been destroyed.
Use threads. And then stop it with an interruption:
Public Thread getThread(final Handler handle, int delay)
{
return new Thread()
{
#Override
public void run()
{
try
{
synchronized(this)
{
Thread.sleep(delay);
handle.post(new Runnable()
{
#Override
public void run()
{
"the code to be exec."
}
});
}
}
catch(Exception e)
{
e.printStackTrace();
}
};
};
}
Or you can use use the postDelayed function
Public Thread getThread(final Handler handle, int delay)
{
return new Thread()
{
#Override
public void run()
{
try
{
synchronized(this)
{
handle.postDelayed(new Runnable()
{
#Override
public void run()
{
"the code to be exec."
}
}, delay);
}
}
catch(Exception e)
{
e.printStackTrace();
}
};
};
}
you will find that there's a little difference between this two methods. To interrupt it, do something like this:
Thread t = getThread(handle, delay);
t.start();
if(t != null)
{
if (t.isAlive())
{
t.interrupt();
}
}
Hope I have helped.
i have an ImageView in which the picture switches every 5s, i am trying to add a pause and
resume button that can stop and restart the action. i am using a Handler, Runnable, and
postDelay() for image switch, and i put the code on onResume. i am thinking about using
wait and notify for the pause and resume, but that would mean creating an extra thread. so
far for the thread, i have this:
class RecipeDisplayThread extends Thread
{
boolean pleaseWait = false;
// This method is called when the thread runs
public void run() {
while (true) {
// Do work
// Check if should wait
synchronized (this) {
while (pleaseWait) {
try {
wait();
} catch (Exception e) {
}
}
}
// Do work
}
}
}
and in the main activity's onCreate():
Button pauseButton = (Button) findViewById(R.id.pause);
pauseButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
while (true) {
synchronized (thread)
{
thread.pleaseWait = true;
}
}
}
});
Button resumeButton = (Button) findViewById(R.id.resume);
resumeButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
while (true) {
// Resume the thread
synchronized (thread)
{
thread.pleaseWait = false;
thread.notify();
}
}
}
});
the pause button seems to work, but then after that i can't press any other button, such as
the resume button.
thanks.
i am using a Handler, Runnable, and
postDelay() for image switch
Why? Why not use postDelayed() and get rid of the Thread and Handler?
void doTheImageUpdate() {
if (areWeStillRunning) {
myImageView.setImageResource(R.drawable.whatever);
myImageView.postDelayed(updater, 5000);
}
}
Runnable updater=new Runnable() {
public void run() {
doTheImageUpdate();
}
};
When you want to start updating, set areWeStillRunning to true and call doTheImageUpdate(). When you want to stop updating, set areWeStillRunning to false. You'll need to work out the edge case of where the user presses pause and resume within 5 seconds, to prevent doubling things up, but I leave that as an exercise for the reader.
If you really want to use a background thread, you will want to learn more about how to use background threads. For example, while(true) {} without any form of exit will never work. There are some good books on the subject, such as this one.
sorry to answer my own question, but the comment section is too small.
i did this (per CommonsWare):
private Runnable mWaitRunnable = new Runnable() {
public void run()
{
doTheImageUpdate();
}
};
private void doTheImageUpdate()
{
try
{
if(bStillRunning)
{
sText = "Step one: unpack egg";
iDrawable = R.drawable.monster2;
t.setText(sText);
mImage = BitmapFactory.decodeResource(getResources(), iDrawable);
imageView.setImageBitmap(mImage);
tts1 = new TTS(getApplicationContext(), ttsInitListener, true);
mHandler.postDelayed(mWaitRunnable, 5000);
}
}
catch (Exception e)
{
Log.e("mWaitRunnable.run()", e.getMessage());
}
}
Button pauseButton = (Button) findViewById(R.id.pause);
pauseButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
bStillRunning = false;
}
});
Button resumeButton = (Button) findViewById(R.id.resume);
resumeButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
bStillRunning = true;
}
});
again pause works but resume doesn't. and i have already simplified my problem by making the text, the image, and delay time the same for all the steps. i was hoping to make these variable, in additional to the number of steps.