i have a function
protected void updateLogs()
in my activity (MainActivity).
I need to call this function with delay. I cann't use this method https://stackoverflow.com/a/9166354/3883330 because i can't call function from other class, because it's not static function. Code with error:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
MainActivity.updateLogs();
}
}, 100);
How can i solve this?
This should work:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
updateLogs();
}
}, 100);
If it doesn't, declare a final object containing this:
final MainActivity main = this; // Just need to make it final
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
main.updateLogs();
}
}, 100);
As Carnal pointed out, it would be cleaner to declare an interface making the method to call public, however since you're calling it from an inner class, I think it's OK that way.
Related
My application content part had too much code. There were about 3000 lines of XML code. This caused my application to startup slowly. (launch in about 8 seconds) I placed the content in 6 viewstub objects. and I created a lot of handlers. Is it a problem? Is it hierarchically correct? How can I do all these handler operations asynctask.
Also how can I make my content lighter and faster.
Thanks in advance!
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
viewStubPager.setLayoutResource(R.layout.viewstubpager);
coachStubPager = viewStubPager.inflate();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
viewStub1.setLayoutResource(R.layout.viewstub1);
coachStub1 = viewStub1.inflate();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
viewStub2.setLayoutResource(R.layout.viewstub2);
coachStub2 = viewStub2.inflate();
viewStub3.setLayoutResource(R.layout.viewstub3);
coachStub3 = viewStub3.inflate();
viewStub4.setLayoutResource(R.layout.viewstub4);
coachStub4 = viewStub4.inflate();
viewStub5.setLayoutResource(R.layout.viewstub5);
coachStub5 = viewStub5.inflate();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Objects.requireNonNull(notificationManager).cancelAll();
sharedPreferencesKeys();
initialize();
calculate();
sharedPrefStartup();
alertDialogClickListener();
changeListener();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
layouts = new int[]{R.layout.vki_slide1, R.layout.vki_slide2, R.layout.vki_slide3, R.layout.vki_slide4, R.layout.vki_slide5, R.layout.vki_slide6, R.layout.vki_slide7, R.layout.vki_slide8, R.layout.vki_slide9};
VKIPagerAdapter = new MyViewPagerAdapter();
vkipager.setAdapter(VKIPagerAdapter);
VKIPagerAdapter.notifyDataSetChanged();
vkipager.setOffscreenPageLimit(10);
vkipager.addOnPageChangeListener(viewPagerPageChangeListener);
pageIndicator.setCount(layouts.length);
pageIndicator.setSelection(0);
bottombar.setVisibility(View.VISIBLE);
}
}, 100);
}
}, 100);
}
}, 100);
}
}, 100);
}
}, 150);
It's a bit late, but this might help others...
I don't know if the code in the question will start faster with my proposed solution (I doubt this will be the case), however, it's way more readable and uses only one Runnable. This can also be used for animations.
I derived this example from the following answer:
https://stackoverflow.com/a/11198037/6423246
Handler mHandler = new Handler();
int inflater = YOUR_CONSTANT_1;
void yourFunction() {
// ...your first inflater code here...
mHandler.postDelayed(mRunnable, your_delay_in_millis);
}
Runnable mRunnable = new Runnable() {
#Override
public void run() {
switch(inflater) {
case YOUR_CONSTANT_1 : {
// ...your second inflater code here...
inflater = YOUR_CONSTANT_2;
mHandler.postDelayed(mRunnable, your_delay_in_millis);
break;
}
case YOUR_CONSTANT_2 : {
// ...your third inflater code here...
inflater = YOUR_CONSTANT_3;
mHandler.postDelayed(mRunnable, your_delay_in_millis);
break;
}
// etcetera
case YOUR_CONSTANT_LAST : {
// ...your last inflater code here...
// in your final case, you could opt to remove callbacks
mHandler.removeCallbacks(mRunnable);
break;
}
}
}
};
i'm working on kind animation program that i'm showing gif with Glide library but i'm using handlers too much for example showing loader and with another handler sync my sequence of showing others gif , i create like this
Handler handler2 = new Handler();
handler2.postDelayed(new Runnable() {
#Override
public void run() {
//showing gif file
}
}, 1000);
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
#Override
public void run() {
}
}, 5000);
Handler handler3 = new Handler();
handler3.postDelayed(new Runnable() {
#Override
public void run() {
}
}, 6000);
and every one this handler are inside each other not exactly like above my question is :
Should i only create one instance from handler and use it ? like bloew
Handler handler = new Handler();
handler .postDelayed(new Runnable() {
#Override
public void run() {
}
}, 1000);
handler.postDelayed(new Runnable() {
#Override
public void run() {
}
}, 5000);
handler.postDelayed(new Runnable() {
#Override
public void run() {
}
}, 6000);
or i should do smoething else ?
i guess my application lagging a little not too much but i want to know the correct way to do it and if there is better way to handle this i appreciate any suggestion.
Should i destroy each handler and runnable after the task finished or not ?
Thanks in advance
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");
}
};
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.
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.