I need to check continously a variable's value. This is a value that I receive from the bluetooth's input stream, this is the reasson why I need to this be continuosly checking it.
What I need to do too, is that when i call the function, it returns to me the value saved in the variable in that moment.
For that, I'm doing this:
private final Handler refresh_handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Runnable refresh_input = new Runnable() {
#Override
public void run() {
bt_read_input = GlobalVar.bt_input; //Save received value in a local variable
refresh_handler.postDelayed(refresh_input, 500);
}
};
}
refresh_handler.post(refresh_input); //Call to the function
This seems to be refreshing the variable every 0,5sec. But I still need that when I call it, it returns to me the actual variable's value, this is, bt_read_input's value in that moment.
How could I implement a function to do this as a timer, but also to return the variable's value to get it when I want?
Try this way
1) create an interface say BloothListener.java
public interface BloothListener {
void onReadValue(String value);
}
2) Create Function say startListing
public void startListing(final BloothListener bloothListener){
final Handler mHandler = new Handler();
try{
final Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
final String bt_read_input = GlobalVar.bt_input;
mHandler.post(new Runnable() {
#Override
public void run() {
bloothListener.onReadValue(bt_read_input);
}
});
}
}, 0, 500);
}catch (Exception e) {
}
}
3) How to use from your activity onCreate() method
startListing(new BloothListener() {
#Override
public void onReadValue(String value) {
// get your value and use it
}
});
I finally achieved this in a very simple way:
private final Runnable refresh_input = new Runnable() {
#Override
public void run() {
bt_read_input = GlobalVar.bt_input;
}
refresh_handler.postDelayed(refresh_input, 250);
}
};
This way I'm refreshing the variable's value every 250ms and when I want to use the value of it, I just havo to call to bt_read_input.
Related
I want a delay for two seconds. and every 2 seconds I want to change the text, and for that, I am using handler like this, but it's not working it's only showing hello. it's not changing at all it only shows what I write second. The code is like this,
private Handler handler = new Handler();
int i=5;
private TextView textView ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.hello);
textView.setText("Android Things !!");
hello_first.run();
}
private Runnable hello_first = new Runnable() {
#Override
public void run() {
textView.setText("Nice Work");
handler.postDelayed(this,5000);
textView.setText("Hello");
handler.postDelayed(this,2000);
i = i+1;
if(i==5)
handler.removeCallbacks(this);
}
};
You are using postDelayed incorrectly. It looks like you expect it to work the same way Thread.sleep would work. However that is not the case.
Here is a correct implementation of what you are trying to achieve:
private Handler handler = new Handler();
private TextView textView;
private int i = 0;
private boolean flip;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.hello);
handler.post(hello_first);
}
private Runnable hello_first = new Runnable() {
#Override
public void run() {
if(++i == 5) {
handler.removeCallbacks(this);
return;
}
if(flip) {
textView.setText("Nice Work");
} else {
textView.setText("Hello");
}
flip = !flip;
handler.postDelayed(this, TimeUnit.SECONDS.toMillis(2));
}
};
I Hope this will work for you.
Handler handler = new Handler();
Runnable task = new Runnable() {
#Override
public void run() {
textView.setText("Nice Work");
handler.postDelayed(this,2000);
textView.setText("Hello");
handler.postDelayed(this,2000);
}
};
task.run();
For Stopping task
handler.removeCallbacks(task);
Its easy to use like
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
textView.setText("Hello");
},2000);
handler.postDelayed(new Runnable() {
#Override
public void run() {
textView.setText("Nice Work");},5000);
A Handler allows you to send and process Message and Runnable objects
associated with a thread's MessageQueue.
Rectify your postDelayed method.
Causes the Runnable r to be added to the message queue, to be run
after the specified amount of time elapses.
DEMO STRUCTURE
textView.setText("Nice Work");
final Handler handlerOBJ = new Handler();
handlerOBJ.postDelayed(new Runnable() {
#Override
public void run() {
// YOUR WORK
textView.setText("Hello");
}
}, 5000); // 5S delay
You can Log and see what happened actually...
Every time you call handler.postDelayed(this, 5000);
it will create two Runnable instance and send them to the handler. So the number of runnable in the queue increase very quickly.
You can set a text list and index, and then throw the runnable to the handler and postDealyed as 2000 milliseconds. Use the text list and index to see what text should be set to the textview.
try this code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.hello);
textView.setText("Android Things !!");
handler.postDelayed(hello_first,5000);
handler.postDelayed(hello_second,2000);
}
private Runnable hello_first = new Runnable() {
#Override
public void run() {
textView.setText("Nice Work");
}
};
private Runnable hello_second = new Runnable() {
#Override
public void run() {
textView.setText("Hello");
}
};
After click button I would like to change its color, then wait one second and change its color back.
This is my code:
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
t.join();
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
}
It doesn't work. I've checked it with more complex code and debugger and it looks like all UI changes are made collectively after finish this function.
I've found this thread: apply ui changes immediately and tried to put setBackgroundColor() and setClickable() into runOnUiThread function:
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
}
});
But it also doesn't work. What should I do?
Something like this :
private final Handler handler = new Handler();
public void click(final View view) {
view.setBackgroundColor(Color.parseColor("#0000ff"));
view.setClickable(false);
handler.postDelayed(() -> {
view.setBackgroundColor(Color.parseColor("#e2e2e2"));
view.setClickable(true);
}, 1000);
}
#Override protected void onPause() {
super.onPause();
handler.removeCallbacks(null);
}
The question is not very clear. However, I am trying to summarize the question that I have understood from your question.
You are trying to set a button's background color on clicking on it and change it back after some time. If this is the situation, then I think your idea of how threads work is wanting.
In your code, the button will change the color immediately as the sleep that you are using is running in another thread (other than UI thread). The code is executed correctly, however, you cannot see the effect of the Thread.sleep as its running in a separate thread.
So all you need to do here is to change the background color again inside the thread. Modify your code like the following.
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
This should work.
I have created a demo trying to show what the code will do.
However, using Handler in case of updating UI elements in this specific case is recommended. Please see the comments below.
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
}
}, 1000);
}
Not sure why that wouldn't work, but I've done something similar with
delayHandler = new Handler();
delayHandler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
//change stuff on ui
}
});
}
}, 1000);
if that doesn't work the only other functional difference in my code is that instead of btn being a final Button it's a private global variable in my activity.
Hope the following code will help :
btn.setBackgroundColor(Color.RED); // color you want for a second
new CountDownTimer(1000, 1000) {
#Override
public void onTick(long arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
btn.setBackgroundColor(Color.BLUE); //to change back color to prior state
}
}.start();
Try this,i think it's work for you..
final Button bPdf = findViewById(R.id.pdf);
bPdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bPdf.setBackgroundColor(Color.parseColor("#0000ff"));
new CountDownTimer(1000, 50) {
#Override
public void onTick(long arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
bPdf.setBackgroundColor(Color.parseColor("#e2e2e2"));
}
}.start();
}
});
I am new in android development and now my launcher activity show only 5 seconds and after that I want to check the user is logged in or not function and perform the actions.
here is my code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exactPreferences = getSharedPreferences("ExactPreference",MODE_PRIVATE);
setContentView(R.layout.activity_landing_page);
session = exactPreferences.getString(Model.getSingleton().SHARED_SESSION_ID,null);
Log.i("Session Id",session);
displayData(); // I want to perform this function after 5 seconds.
}
private void displayData() {
if(session.equals("")){
Intent loginIntent = new Intent(LandingPage.this,
LoginActivity.class);
startActivity(loginIntent);
Log.i("User Logged In", "False");
}
else
{
Intent objIntent = new Intent(LandingPage.this,
IndexPageActivity.class);
startActivity(objIntent);
Log.i("User Logged In", "True");
}
}
You can use the Handler to add some delay.Call the method displayData() as below so that it will be executed after 5 seconds.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
displayData();
}
}, 5000);
Note : Do not use the threads like Thread.sleep(5000); because it will block your UI and and makes it irresponsive.
Assign millisDelayTime variable with the milliseconds you desire to cause a delay. mActivity is an object of Activity for providing Application Context. In your case millisDelayTime should be initialized with 5000
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//your code here
}
}, millisDelayTime);
}
});
Use a CountDownTimer
// There's a TextView txtCount in Main Activity
final int secs = 5;
new CountDownTimer((secs +1) * 1000, 1000) // Wait 5 secs, tick every 1 sec
{
#Override
public final void onTick(final long millisUntilFinished)
{
txtCount.setText("" + (int) (millisUntilFinished * .001f));
}
#Override
public final void onFinish()
{
txtCount.setText("GO!");
finish();
// Time's up - Start the Login Activity
final Intent tnt =
new Intent(getApplicationContext(), LoginActivity.class);
startActivity(tnt);
}
}.start();
Since, Handler is now deprecated so use this code :
new Handler(Looper.myLooper()).postDelayed(new Runnable() {
#Override
public void run() {
//do what you want
}
}, 5000);
Try this, code create CountDownTimer with one tick
timer = new CountDownTimer(5000, 5000)
{
public void onTick(long millisUntilFinished)
{
}
public void onFinish()
{
displayData();
}
};
timer.start();
long delay = 1000;
long period = 50000;
Timer task = new Timer();
task.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
getDriver(sessionManager.getKEY(), ride_id);
}
}, delay, period);
For kotlin way
Handler().postDelayed({
//do something
}, 5000)
When possible, try to avoid using postDelayed. It is a bad practice, since it can lose the reference to the objects that you want to draw on your screen and cause a NPE. Use a Handler instead. First of all, create a global variable Handler in which you will have to "handle" the logic for your code. Do so by using the function handleMessage.
Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
if(msg.what == 1){
// your code here
}
}
};
Then, wherever you want to execute it, just call the function:
// 1 is the ID of your process
handler.sendEmptyMessageDelayed(1, 5000);
Please remember that in the onDestroyView method (in a Fragment) or the onDestroy (in an Activity) you will have to call
handler.removeMessages(1)
The best option to achieve this is using a Handler:
int TIME = 5000; //5000 ms (5 Seconds)
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
function(); //call function!
}
}, TIME);
I am performing two class which is extending ASyncTask and both have different functions but because of the second class my first class is lagging. So what i want to know is, is there any better solution to code in such a way that both of the operation will perform the task without making other operation to wait?
Updated with code
For the first call in the onCreate()
new connection().execute(); //
Some task performed by the same class called
public class connection extends AsyncTask {
#Override
protected Object doInBackground(Object... arg0) {
//some operation
return value;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
String m = String.valueOf(o);
if (o != null) {
someoperation
} else {
edittxt.setTextColor(Color.RED);
edittxt.setText("No Internet Connection");
}
}
}
similarly i am performing the other class that i have.
You can use AsyncTask.executeOnExecutor with THREAD_POOL_EXECUTOR, the default executor is SERIAL_EXECUTOR.
You can create two separate threads and perform your operations. It will quarantine, that all operations will be performed async.
final Handler handler = new Handler();
Thread operation1 = new Thread(new Runnable() {
#Override
public void run() {
doOperation1();
handler.run(new Runnable(){
#Override
public void run() {
onPostExecute1();
}
});
}
});
Thread operation2 = new Thread(new Runnable() {
#Override
public void run() {
doOperation2();
handler.run(new Runnable(){
#Override
public void run() {
onPostExecute2();
}
});
}
});
operation1.start();
operation2.start();
I have a series of postDelayed handlers. I'm having trouble to set a mathode that stops the handlers when the user is tapping on the stop button at any time I he wants.
I'll appreciate any help someone able to provide.
Thanks
while (!lessonIsRunning) {
Handler handler0 = new Handler();
handler0.postDelayed(new Runnable() {
#Override
public void run() {
plate1.setVisibility(ImageView.VISIBLE);
plate2.setVisibility(ImageView.VISIBLE);
plate3.setVisibility(ImageView.VISIBLE);
}
}, 6000);
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
#Override
public void run() {
apples1.setVisibility(ImageView.VISIBLE);
}
}, 9000);
Handler handler2 = new Handler();
handler2.postDelayed(new Runnable() {
#Override
public void run() {
plus1.setVisibility(TextView.VISIBLE);
}
}, 9250);
}
public void stopLesson(View V){
}
instead of writing the Runnable task in an anonymous way you must define it with a name, so that later you will have a link to it to remove:
//there is no need for multiple handlers
//handler must be declared outside all functions, in order for you to use it everywhere.
Handler handler = new Handler();
Runnable myFirstTask = new Runnable (){
#Override
public void run() {
plate1.setVisibility(ImageView.VISIBLE);
plate2.setVisibility(ImageView.VISIBLE);
plate3.setVisibility(ImageView.VISIBLE);
} };
Runnable mySecondTask = new Runnable(){
#Override
public void run() {
plus1.setVisibility(TextView.VISIBLE);
}
};
Runnable myThirdTask = new Runnable(){
#Override
public void run() {
apples1.setVisibility(ImageView.VISIBLE);
} }
//you can put different tasks on the same handler object
while (!lessonIsRunning) {
handler.postDelayed(myFirstTask,6000);
handler.postDelayed(mySecondTask,9250);
handler.postDelayed(myThirdTask,9000);
}
public void stopLesson(View V){
//notice that you don't need these, because the handlers are not recursive
//you don't have lines "handler.postDelayed(sameTask,someTime);"
//in your run Method of the runnable
if(handler!=null){
handler.removeCallbacks(myFirstTask);
handler.removeCallbacks(mySecondTask);
handler.removeCallbacks(myThirdTask);
//if this method is inside onPause or onDestroy add this line as well:
handler=null;
}
}
you can give
handler0.removeCallbacksAndMessages(null);
handler1.removeCallbacksAndMessages(null);
handler2.removeCallbacksAndMessages(null);
a try. The doc says when you submit a null token all callbacks and message are removed.