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);
}
});
Related
I'm developing an app that gets values from an Arduino in Real Time.
It gets the angle of a machine non stop.
I need my app to get the max value from all the values it received from the Arduino and when it reaches 0 degrees after the 1st movment start another function.
Or if you can, how do I call functions when that value hits a specific value?
for example, on the image, how can I make the app call another function when the pointer hits the green range.
Thnaks
I tried something like this but doesn't work.
if (x>y){
y=x;
}
test5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
x=x+5;
Log.d("valuey", Integer.toString(y));
Log.d("valuex", Integer.toString(x));
}
});
im going to try something like this
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(100);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (x>y){
y=x;
}
test5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
x=x+5;
Log.d("valor2", Integer.toString(y));
Log.d("valor3", Integer.toString(x));
}
});
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
I find out another way that makes more sence in this case.
Set an SpeedChangeListener that calls the same function.
speedView.setOnSpeedChangeListener(new OnSpeedChangeListener() {
#Override
public void onSpeedChange(Gauge gauge, boolean isSpeedUp, boolean isByTremble) {
if ((i>=-1 && i < 2) || i==4 || i==7) {
calculo();
avaliacao();
}
}
});
I want to press volume button programatically. In Java it is possible using the robot class, but in Android there is no robot class.
I am wondering how to achieve this in Android.
I would suggest you to increase/decrease the volume programmatically which would be a tad bit easier, however if you want to use it for some other process then you can check the code below -
EDIT - The snippet I gave before doesn't work, but this one does. It uses a runnable so the try catch block is necessary.
new Thread(new Runnable() {
#Override
public void run() {
try {
Instrumentation inst = new Instrumentation();
//This is for Volume Down, change to
//KEYCODE_VOLUME_UP for Volume Up.
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_VOLUME_DOWN);
}catch(InterruptedException e){}
}
}).start();
how about this
private abstract class SimpleButton extends Button {
public SimpleButton(String text) {
super(TechDemoLauncher.this);
setText(text);
setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
onButtonPressed();
}
});
}
public abstract void onButtonPressed();
}
after that you can just implement the onButtonPressed() method like this
private void Example(String string) {
yourLayout.addView(new SimpleButton(string) {
#Override
public void onButtonPressed() {
//insert your code
}
});
}
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..
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.
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.