I am making an android app that requires a runnable. I am starting a new activity from the runnable. The new activity comes up and works fine. The issue is that when the call is made to start the activity, it is incredibly slow. It takes a full 5 seconds to start the activity when I want it to be instantaneous.
Boolean handlerrun=true;
Intent intent= new Intent(this,newactivity.class);
int somevalue=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameactivity);
handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
if(handlerrun){somevalue++;}
if(somevalue>500){
handlerrun=false;
startActivity(intent);
finish();
}
handler.postDelayed(this, 1);}
}
};
handler.postDelayed(r, 1);
}
The activity starts when somevalue is greater than 500. To stop the handler from increasing the value of somevalue, I use a boolean handlerrun, which only runs the handler when it is true. When somevalue is greater than 500, handlerrun= false so the handler doesn't increase the value. I tried using the handler.removeCallbacksandMessages() method but it didn't work. Logcat doesn't give me any errors.Any help would be appreciated.
You could try something like this:
#Override
protected void onResume() {
super.onResume();
if(done){
return;
}
done = true;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent(getApplicationContext(), YourActivity.class));
finish();
overridePendingTransition(0, 0);
}
}, 5000);
}
That will start YourActivity after 5 seconds approximately.
Hope it helps.
Related
I am using broadcastreceiver to update the Activity every minute, however, I want to change it to every 2 minutes. How can I achieve that?
Below is the code for my function -
private void startMinuteUpdated() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_TIME_TICK);
minuteUpdateReceiver= new BroadcastReceiver() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onReceive(Context context, Intent intent) {
lastUpdatedTimeTextDeparture.setText(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")));
}
};
registerReceiver(minuteUpdateReceiver, intentFilter);
}
#Override
protected void onResume() {
super.onResume();
startMinuteUpdated();
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(minuteUpdateReceiver);
}
You can alter your current implementation to read the minutes from current time and if its remainder by 2 is 0 then do your stuff, or else return. Doing this will allow you to update when the minutes are in even value (i.e. running every second minute).
if (Calendar.getInstance().get(Calendar.MINUTE) % 2 != 0){
// don't proceed further
return;
}
// update the activity
I have an Android project which is sending a Broadcast every second and am trying to figure out how to stop it after a click.
My broadcast code is:
Intent broadcastIntent = new Intent ("send broadcast");
sendBroadcast(broadcastIntent);
stoptimertask(); //it is stopping broadcast for a second.
You can define two methods: one that start a Timer to send a broadcast every second and a second one that stop the Timer.
Timer timer;
private void startBroadcastLoop() {
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
// Send broadcast
Intent broadcastIntent = new Intent ("send broadcast");
sendBroadcast(broadcastIntent);
}
},0,1000); // Send broadcast every second
}
private void stopBroadcastLoop() {
if(timer!=null){
timer.cancel();
timer = null;
}
}
And then on your button, call the right function according to the state of a boolean:
sendBroadcastBool = false;
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
// If broadcast not sent yet
if (!sendBroadcastBool) {
startBroadcastLoop();
sendBroadcastBool = true;
}
else {
stopBroadcastLoop();
sendBroadcastBool = false;
}
}
});
Best
At the moment, in each one of my activities I have this method:
private void registerReceiverClose(){
Activity activity = this;
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("CLOSE_ALL");
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
activity.finish();
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
and this one as well:
#Override
protected void onDestroy() {
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
They're triggered by the following logout button:
Button logout = findViewById(R.id.logout_button);
logout.setOnClickListener(click -> {
Intent intent = new Intent("CLOSE_ALL");
this.sendBroadcast(intent);
});
One thing that I'm sure is not closing in the right way, is that I have this code:
private static final ScheduledExecutorService pollingScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
private static final Object lock = new Object();
private static ScheduledFuture<?> currentRunningTask;
public void longPoll() {
synchronized (lock) {
if (currentRunningTask != null) {
currentRunningTask.cancel(true);
}
try {
currentRunningTask = pollingScheduledExecutor.scheduleAtFixedRate(this, 0, 3, TimeUnit.SECONDS);
} catch (Exception ignored) {
}
}
}
public void request() {
Thread requestThread = new Thread(this);
requestThread.start();
}
which continues to issue requests even after I think I should be logged out, which causes errors on the server.
How can I make sure all the threads stop gracefully and the application closes down in the right way?
You could wrapthe polling code inside of a Service. This service can then be stopped using
Intent intent = new Intent(MainActivity.this, MyService.class);
stopService(intent);
Inside of the service, you can override onDestroy() to clean resources up.
TL;DR: My intent takes too much time to start from a different thread, whereas starting from the main thread is very fast. I dont actually know if this is a problem with threads or with the onFinish method
So, I have a countdown timer. It counts down from twenty seconds, and onFinish() I have an intent. I am also periodically setting the text of my textView based on millisUntilFinished. I noticed, that after the textView says 1 second left, the intent starts after 3 seconds.
But, if I am switching activities by using an intent from OUTSIDE of the onFinish method the next activity starts quickly. So,
Why does starting an intent from a the onFinish method take longer than usual?
According to my little test with my timer, I decided that I need a better and faster way to start my intent, since clearly, the onFinish method launches after more time then the timer actually starts. So, what should I do to start my intent faster? I need it to be immediate...
public void startTimer() {
timer = new CountDownTimer(20000, 1000) {
public void onTick(long millisUntilFinished) {
int seconds = (int) millisUntilFinished/1000;
timetext.setText(seconds + ":00");
}
public void onFinish() {
Intent intent = new Intent(MainActivity.this, GameOver.class);
intent.putExtra("score", score); // pass your values and retrieve them in the other Activity using keyName
intent.putExtra("classname", "com.example.ruchir.swapproperties.MainActivity");
startActivity(intent);
}
}.start();
}
Thanks,
Ruchir
Try placing the startActivity(intent) outside of the timer as such:
public void startTimer() {
timer = new CountDownTimer(20000, 1000) {
public void onTick(long millisUntilFinished) {
int seconds = (int) millisUntilFinished/1000;
timetext.setText(seconds + ":00");
}
public void onFinish() {
Intent intent = new Intent(MainActivity.this, GameOver.class);
intent.putExtra("score", score); // pass your values and retrieve them in the other Activity using keyName
intent.putExtra("classname", "com.example.ruchir.swapproperties.MainActivity");
}
}.start();
startActivity(intent);
}
You can have a try :
public void onFinish() {
cancel(); //Cancel the countdown
Intent intent = new Intent(MainActivity.this, GameOver.class);
intent.putExtra("score", score); // pass your values and retrieve them in the other Activity using keyName
intent.putExtra("classname", "com.example.ruchir.swapproperties.MainActivity");
startActivity(intent);
}
`
I am trying to make my application launcha splash screen for 5 seconds while initializing various web services in the background. Here is my code:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Splash screen view
setContentView(R.layout.splashscreen);
final SplashScreen sPlashScreen = this;
// The thread to wait for splash screen events
mSplashThread = new Thread()
{
#Override
public void run()
{
try {
synchronized(this){
// Wait given period of time or exit on touch
wait(5000);
}
}
catch(InterruptedException ex)
{
}
finally
{
finish();
// Run next activity
Intent intent = new Intent();
intent.setClass(sPlashScreen, Splash_testActivity.class);
startActivity(intent);
stop();
}
}
};
mSplashThread.start();
for (int i=0;i<100;i++)
Log.d("splash test", "initialize web methods");
}
Now what I think should happen is that while the splash screen is displayed, the application should log "initialize web methods."
But what actually happens is that the log is added only after the slash screen disappears.
What am I doing wrong??
Try to do it this way. This tutorial is simple and flexible. This is what you need:
// You initialize _splashTime to any value
// thread for displaying the SplashScreen
Thread splashTread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while(waited < _splashTime)) {
sleep(100);
waited += 100;
}
}
} catch(InterruptedException e) {
// do nothing
} finally {
finish();
startActivity(new Intent("com.droidnova.android.splashscreen.MyApp"));
stop();
}
}
};
splashTread.start();
Note: This code is adopted from the above url.
Run your Thread Using Handler or AsyncTask.