I have create a method that after 5 seconds, set ImageView's alpha to 0.4 using handler.postDelayed.
The problem is that the method is called multiple times because of it is located inside of Touch-listener's MotionEvent.ACTION_UP. So I am looking for a method that detect if the handler.postDelayed is active.
private Handler handler;
private Runnable runnable;
private init(){
runnable = new Runnable(){
#Override
public void run(){
ImageView.setAlpha(0.4f);
}
}
}
private void setAlpha(){
handler = new Handler();
handler.postDelayed(runnable,5000);
}
private void cancleHandler(){
handler.removeCallbacks(runnable);
}
1: Keep a reference to the Handler instead of a creating a brand new one each time.
2: Check if the runnable is already posted and don't post a new one if it is.
private Handler handler;
private Runnable runnable;
private init(){
handler = new Handler();
runnable = new Runnable(){
#Override
public void run(){
ImageView.setAlpha(0.4f);
}
}
}
private void setAlpha(){
if (!handler.hasCallbacks(runnable)) {
handler.postDelayed(runnable,5000);
}
}
private void cancleHandler(){
handler.removeCallbacks(runnable);
}
Try to removing the callback before adding another one, and using the same handler instance:
private Handler handler;
private Runnable runnable;
private init(){
handler = new Handler();
runnable = new Runnable(){
#Override
public void run(){
ImageView.setAlpha(0.4f);
}
}
}
private void setAlpha(){
handler.removeCallbacks(runnable);
handler.postDelayed(runnable,5000);
}
private void cancleHandler(){
handler.removeCallbacks(runnable);
}
Related
I use code like below for periodic execution
but i am suspecting a memory leak
Maybe my code is wrong?
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
if(isRunning)
{
...code
}
handler.postDelayed(this, 5000);
}
};
handler.postDelayed(runnable, 5000);
This is the code that uses another handler
private Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
mHandler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(#NonNull Message msg) {
return true;
}
});
}
I searched for a way to update UI from another thread, and found that the available approach is to use Handler.post(Runnable) as shown in the code snippet below:
public class MyClass extends Activity {
private final Handler myHandler = new Handler();
final Runnable updateRunnable = new Runnable() {
public void run() {
// Update UI
}
};
private OnClickListener buttonListener = new OnClickListener() {
public void onClick(View v) {
new Thread(new Runnable() {
myHandler.post(updateRunnable);
}).start();
}
};
}
Instead can't we use Handler.sendMessage and do the UI updates from main UI thread in handleMessage():
public class MyClass extends Activity {
private final Handler myHandler = new Handler();
private Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what) {
// Do logic here
}
}
};
private OnClickListener buttonListener = new OnClickListener() {
public void onClick(View v) {
new Thread(new Runnable() {
myHandler.sendEmptyMessage(0);
}).start();
}
};
}
I'm sorry if this is a very basic question, however I'm quite confused with the above two approaches.
You need to use runOnUiThread. You can post a runnable which does the UI operation to main thread as follows,
public class Utils {
public static void runOnUiThread(Runnable runnable){
final Handler UIHandler = new Handler(Looper.getMainLooper());
UIHandler .post(runnable);
}
}
Utils.runOnUiThread(new Runnable() {
#Override
public void run() {
// UI updation related code.
}
});
Read more at:
android: update UI from another thread in another class
Updating UI / runOnUiThread / final variables: How to write lean code that does UI updating when called from another Thread
https://developer.android.com/training/multiple-threads/communicate-ui.html
I tried to create a small timer for my programm but this code below is not working and i cant find the issue
private int mInterval = 5000;
private Handler mHandler;
// at the bottom of my onCreate() methode:
mHandler = new Handler();
startRepeatingTask();
}
// on create ends here
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
myview.loadUrl(readFromFile());
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
I really would appreciate your help.
Something like this should work :)
//set variables
private int mInterval = 5000;
private Handler handler = new Handler();
//start runnable
runme.run();
private Runnable runme = new Runnable()
{
public void run()
{
//repeat after 5000 milliseconds
handler.postDelayed(this, mInterval );
}
};
//stop runnable
handler.removeCallbacks(runme);
try this..
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
// do something here...
handler.postDelayed(this, 5000); // for interval...
}
};
handler.postDelayed(runnable, 2000);
Try this
private int mInterval = 5000;
private Handler mHandler;
// at the bottom of my onCreate() methode:
mHandler = new Handler();
mHandler.postDelayed(mStatusChecker,mInterval);
}
// on create ends here
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
myview.loadUrl(readFromFile());
//if you want to repeat the thread infinitely,then add below code also. Else remove it
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
Use Handler.post() or Handler.postDelayed() to start a Handler.
private int mInterval = 5000;
private Handler mHandler;
// at the bottom of my onCreate() methode:
mHandler = new Handler();
mHandler.post(mStatusChecker);
//mHandler.postDelayed(mStatusChecker, mInterval);//or use this method
//startRepeatingTask();
// on create ends here
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
myview.loadUrl(readFromFile());
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
//void startRepeatingTask() {
// mStatusChecker.run();
//}
You may need to add android.permission.WRITE_EXTERNAL_STORAGE for read file in storage, and android.permission.INTERNET for load url.
I have the below singleton handler class
public class MyHandler
{
private static Handler handler;
private static boolean isRunning;
public static Handler getHandler(Runnable myRunnable)
{
if (handler == null)
{
initHandler(myRunnable);
}
return handler;
}
private static void initHandler(Runnable myRunnable)
{
handler = new Handler();
isRunning = true;
handler.postDelayed(myRunnable, 5000);
}
public static void reRunHandler(Runnable myRunnable)
{
isRunning = true;
handler.postDelayed(myRunnable, 45000);
}
public static void stopMyHandler()
{
isRunning = false;
handler.removeCallbacksAndMessages(null);
}
}
However, how can I update my UI from here ? As the runnables are inside my activity. Apparently I cannot use getHandleMessage to communicate with it.
If you need more code, how am I using this, I can share.
It's very simple:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
//do whatever you want on the UI thread
}
});
Handle has functions for this purposes:
private final Handler handler = new Handler() {
public void handleMessage(Message msg) {
// here you can get data from Message and update your UI. runs in UI thread
}
};
If you will send message with data to your Handler use next code:
Message m = new Message();
Bundle b = new Bundle();
b.putInt("myNumber", 5); // for example
m.setData(b);
myHandler.sendMessage(m);
How can i pause the handler.postDelayed() timer using a button. So when i click the same button again the handler.postDelayed() timer should resume.
handler.postDelayed(counterz, 60);
Handler does not have a timer to tweak. You are posting to event-queue of a thread, where a lot of other stuff is running as well.
You can cancel posted Runnable's:
handler.removeCallbacks(counterz);
And post again, to resume.
Handler does not have a pause method. You need to cancel and run again.
http://developer.android.com/reference/android/os/Handler.html#removeCallbacks(java.lang.Runnable)
public final void removeCallbacks (Runnable r)
Remove any pending posts of Runnable r that are in the message queue.
When not required you need to call m_handler.removeCallbacks(m_handlerTask) to cancel the run. If you need again you need to run the the task again.
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run(); // call run
Suppose you use a timer. Even timer does not have pause method.
public class YourActivity extends AppCompatActivity {
private static boolean handlerflag=false;
private Handler handler;
private Runnable runnable;
private int myind=0,index=0,count=0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activtiy);
//oncreate exe only
handlerflag=true;
handler = new Handler();
startyourtime(0);
}
private void startyourtime(int a) {
myind=0;
for (index=a; index<10 ;index++) {
myind++;
runnable=new Runnable() {
count++;
#Override
public void run() {
//your code here
}
};handler.postDelayed(runnable, Constants.TIME_LIMIT * myind);
}
#Override
protected void onPause() {
super.onPause();
handlerflag=false;
handler.removeCallbacksAndMessages(null);
}
#Override
protected void onResume() {
super.onResume();
if(!handlerflag)
{
startyourtime(count);
}
}
}