Java method not executing after scheduled time - java

I'd like to execute a method 10 seconds after I launch an Intent:
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(GOOGLE_VOICE_SEARCH_PACKAGE_NAME);
startActivity(launchIntent);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
SonrLog.d(TAG, "TIMEOUT, reconnecting!");
reconnectSONR();
}
}, 10000); //10 second timeout
The Intent launches, and my code steps over the Handler, but nothing gets printed or gets called.
How can I get this to work?

Well I tried the above code and it is working fine. And I can see the log Log.d(TAG, "TIMEOUT, reconnecting!"); printed in the log. Code that i used.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(GOOGLE_VOICE_SEARCH_PACKAGE_NAME);
startActivity(launchIntent);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Log.d(TAG, "TIMEOUT, reconnecting!");
}
}, 10000); //10 second timeout
}
});
NOTE: GOOGLE_VOICE_SEARCH_PACKAGE_NAME is pointed to some other package as it is just for testing.

Related

SetContentView does not work while I'm using handler

I am trying to make app sleep using Thread. I have got 2 solutions but one of them causes a problem.
This is a shorter code which works perfectly:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome);
final Handler goToMenu = new Handler();
goToMenu.postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(getApplicationContext(), Menu.class);
startActivity(i);
}
},5000);
}
But this one is problematic. When I put the time in millis to make app wait it works and the second Activity starts but the R.layout.welcome does not appear. The app just waits with a gray background until the startActivity(i) gets executed.
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome);
final Handler goToMenu = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
Intent i = new Intent(getApplicationContext(), Menu.class);
startActivity(i);
}
};
Runnable run = new Runnable() {
#Override
public void run() {
try {
synchronized (this) {
wait(5000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.d(TAG, "Waiting didnt work!!");
e.printStackTrace();
}
goToMenu.sendEmptyMessage(0);
}
};
Thread waitThread = new Thread(run);
waitThread.run();
What is wrong?
To start a new thread, use Thread#start() and not Thread#run().
run() just executes the Runnable synchronously i.e. blocking the current thread.
use
Handler.postDelayed(new Runnable(){}, DELAY_TIME) instead
for your case
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(getApplicationContext(), Menu.class);
startActivity(i);
}
}, 5000);
To Show thelayout, Activity's onCreate() method should run completely. In your second code there is a thread. That thread stops your code compilation for 5000 milliseconds. That means your second code stops and wait 5 seconds in wait(5000); line. Therefore onCreate() method not completes.
You have used Handler().postDelayed() your first code. This method don't stuck the code. It is a background task. it works synchronously.
I hope your answer is here.

splash screen activity appears when exiting app

Whenever I try to exit from my app by pressing back button twice, splash screen appears and it freezes until i press back button again. So I need to press back button three times to exit from my app. Please help me to exit from app with only two back button press.
The java code in project as follows:
public void onBackPressed()
{
if (doubleBackToExitPressedOnce)
{
super.onBackPressed();
MapsActivity.this.finish();
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click Back again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
doubleBackToExitPressedOnce = false;
}
}, 2000);
}
my splash screen code as follows:
public class SplashScreen extends AppCompatActivity {
ImageView logoView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
Animation anim1 = AnimationUtils.loadAnimation(this,R.anim.anim_down);
logoView = findViewById(R.id.logoview);
logoView.setAnimation(anim1);
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
Intent next_scrn = new Intent(SplashScreen.this,MapsActivity.class);
startActivity(next_scrn);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
},2500);
}
}
you should to finish splashActivity after start new activity, so use :
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
Intent next_scrn = new Intent(SplashScreen.this,MapsActivity.class);
startActivity(next_scrn);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
SplashScreen.this.finish();
}
},2500);
Add finish(); after below code.
Intent next_scrn = new Intent(SplashScreen.this,MapsActivity.class);
startActivity(next_scrn);
You must finish() splash screen like as below than your condition on BackPress work
Intent next_scrn = new Intent(SplashScreen.this,MapsActivity.class);
startActivity(next_scrn);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
finish();

How to detect taps on a button whilst a delay caused by postDelayed Handler

I want to solve a problem that I have been trying to do so the last couple of days but I dont have that much experience and I couldnt find the solution enywhere else.
Anyway,
In my app I have a button in wich I have implemented the onClickClistener in order to respond to touch and inside that I have added a Handler which adds a delay and after that some code is being executed. My problem is that i want to detect any tap of the button whilst the delay is happening and the postDelyed function doesn't allow me to do so. How can I actually do that?
I've posted my code that is related on that.
Thanks in advance!
P.S(I dont mind not using this postDelayed thing.)
Button button = findViewById(R.id.myButtonId);
button.setOnClickListener(new View.OnClickListener){
#Override
public void onClick(View v) {
.......
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do some thing after the delay
}
}, randomDelay);
//Do other things
}
});
boolean previousTapDetected;
...
button.setOnClickListener(new View.OnClickListener){
#Override
public void onClick(View v) {
.......
if(previousTapDetected) {
//We got a tap during the delay
}
Handler handler = new Handler();
previousTapDetected = true;
handler.postDelayed(new Runnable() {
#Override
public void run() {
previousTapDetected = false;
//Do some thing after the delay
}
}, randomDelay);
//Do other things
}
});

What's a "nice" way of stopping a (linear) runnable in case of activity switch?

I have a thread that will do some processing, then has runnable code which will display the results on the screen. The issue is that if the user presses the back arrow while the runnable is between two lines of display code, the next line will crash as the activity no longer exists.
The below code accomplishes the goal, but I hate having if statements before each line. Is there a better way?
#Override
public void onBackPressed() {
super.onBackPressed();
imgThread.interrupt();
}
private void processImage(){
final Handler mHandler = new Handler(Looper.getMainLooper());
progress = new ProgressDialog(this);
progress.setMessage("TEXT");
progress.setIndeterminate(true);
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.show();
imgThread = new Thread(){
#Override
public void run() {
//Process the image a bit
mHandler.post(new Runnable() {
#Override
public void run() {
if(!imgThread.isInterrupted())
imageView.setImageBitmap(mDisplayBitmap);
if(!imgThread.isInterrupted())
progress.setMessage("TEXT TEXT");
if(!imgThread.isInterrupted())
progress.show();
}
});
//More processing
mHandler.post(new Runnable() {
#Override
public void run() {
if(!imgThread.isInterrupted())
addScreenListener();
if(!imgThread.isInterrupted())
determineHelpToast("TEXT TEXT TEXT", Toast.LENGTH_LONG);
if(!imgThread.isInterrupted())
progress.dismiss();
}
});
}
}; imgThread.start();
}
The really safe way to do this is to modify your Runnable so that it never references the Android Context (Activity, etc.).
The easiest way to do this is to communicate changes to the Activity via an event bus.

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

I am using simple thread to execute the httpGet to server when a button is clicked, but I get this after execution.
Button b_back = (Button) findViewById(R.id.bback);
b_back.setOnClickListener(this);
Button b_sign_up = (Button) findViewById(R.id.signup_button);
b_sign_up.setOnClickListener(this);
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
switch (arg0.getId())
{
case R.id.bback:
Intent i = new Intent(this, MainSwitch.class);
finish();
startActivity(i);
break;
// More buttons go here (if any) ...
case R.id.signup_button:
if(username.getText().toString().equalsIgnoreCase("") ||
password.getText().toString().equalsIgnoreCase("") ||
email.getText().toString().equalsIgnoreCase(""))
{
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setMessage("Please fill in all the gaps!");
dialog.show();
}
else
{
//****** Call method that sends the information to server.
Thread background = new Thread (new Runnable()
{
public void run()
{
// Call the time consuming method
handler.sendEmptyMessage(0);
}
});
background.start();
}
}
}
private Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
Toast.makeText(getApplicationContext(),
"Done thread",
Toast.LENGTH_SHORT).show();
}
};
The errorline you get:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
is typically linked to problems where you try to do stuff to UI-elements on a non-UI-thread.
I suppose that by stating // Call the time consuming method you have left out some of your code. The fact that this time consuming method runs on a regulare Thread means it cannot interact with UI-elements.
If you post more code (and also which specify the line where the error occurs) we can probably provide more info on how to solve it.

Categories