1

Is there a way to stop a runnable after only one execution of a method?

I have created this code to delay the starting of the method "getPreferences" but when I run the app my next activity that "getPreferences" sends me to gives this problem of the screen refreshing?
Is this down to the runnable still continuing to loop and how can I kill it after one execution?

 import android.os.Bundle;
 import android.os.Handler;
 import android.app.Activity;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.view.Menu;

 public class StartScreen extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_start_screen);



    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() { 

    getPreferences();

      }}, 10000);

    }


private void getPreferences() {
    // TODO Auto-generated method stub
    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String name = sharedPreferences.getString("NAME", "");



    if (name != null) {
        // the key does not exist



                Intent intent=new Intent(StartScreen.this,InitialPreferences.class);
                startActivity(intent);
            }

     if (name == "NAME"){
        // handle the value


                Intent intent=new Intent(StartScreen.this,MainActivity.class);
                startActivity(intent);
     }     

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.start_screen, menu);
    return true;
}

  }

InitialPreferences avtivity....

 import android.content.SharedPreferences;
 import android.os.Bundle;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup; 
import android.widget.TextView;

  public class InitialPreferences extends StartScreen implements OnClickListener {

EditText editText1;
Button button1;
TextView textView1;
 RadioGroup radioGroup;
 RadioButton radioPosistionButton;   

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.initial_preferences);

   //  waitTimer.cancel();

    textView1 = (TextView)findViewById(R.id.textView1);
    editText1 = (EditText)findViewById(R.id.editText1);
    button1 = (Button)findViewById(R.id.button1); 
    radioGroup = (RadioGroup) findViewById(R.id.radioGroup);  




 }
 @Override
 protected void onStart(){
 //waitTimer.cancel();

 LoadPreferences();
 super.onStart();
  }
 private void SavePreferences(String key, String value){
    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(key, value);
    editor.commit();
   }

 private void LoadPreferences(){
    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String name = sharedPreferences.getString("NAME", "");
    textView1.setText(name);       

 }
 @Override
 public void onClick(View v) {
// TODO Auto-generated method stub
  SavePreferences("NAME", editText1.getText().toString());


// get selected radio button from radioGroup
int selectedId = radioGroup.getCheckedRadioButtonId();

// find the radio button by returned id
    radioPosistionButton = (RadioButton) findViewById(selectedId);


 }


 }
J4C3N-14
  • 686
  • 1
  • 13
  • 32
  • Wait, so what is the issue here? what is the problem you are talking about "gives this problem of the screen refreshing"? Can you explain more? Also, may I ask why are you starting an activity using `Runnable()`? – LuckyMe Jul 23 '13 at 05:09
  • http://stackoverflow.com/a/8686884/726863 – Lalit Poptani Jul 23 '13 at 05:10
  • Hi, sorry if my question was vague. Yes the next activity either initial preferences or main activity keeps reloading after 10 seconds @lalit poptani, thanks ill read that over tonight. – J4C3N-14 Jul 23 '13 at 11:00
  • @LalitPoptani hi, I have been looking at your previous answer that you directed me to, can you show e how to incorporate this into my code? Thank you – J4C3N-14 Jul 24 '13 at 21:32
  • @J4C3N-14 I have edited my answer. I think the problem is that you are extending StartScreen in InitialPreference instead of Activity. I suggest you take a look to PreferenceActivity for extending from your InitialPreferences (see link in my answer) – AitorTheRed Jul 26 '13 at 06:03

4 Answers4

1

The method run is only executed once. If you wish for a neverending loop, you need to include something like a while(true).
Describe better your problem, as I don't understand it very well. Is the problem that the next activity loads twice? Under what circumstances? Could you post the code of your next activity? Which activity is loading? InitialPreferences or MainActivity?
Be awere that by including the code in the onCreate of the Activity it will be executed once for everytime the activity is re-created (for instance, like when you change your phone from landscape to portrait, the activity is recreated, calling onCreate again).

EDIT 1: The main problem you have is that your InitialPreference class extends StartScreen, and in your onCreate method, you're call to super will trigger another postDelayed, launching yet another InitialPreference and so on.
Is there any reason why are you extending StartScreen instead of Activity? I think with this change your will have your problem solved. And of course, if you are doing a settings Activity, I would suggest the use of PreferenceActivity. You can check the documentation http://developer.android.com/guide/topics/ui/settings.html

AitorTheRed
  • 553
  • 4
  • 15
  • Hi thanks for your answer, yes you are right the problem is that the next activity (initial preferences) keeps reloading not once or twice but indefinitely every 10 seconds or whatever amount of time I put. Can't post the code of initial preferences the mo as at work but will do later. I assumed I need to stop this activity onpause but that didn't seem to work either... As you may tell I'm still very much a novice at coding so thanks for your help and advice on not using this in onCreate. – J4C3N-14 Jul 23 '13 at 10:52
  • hi, thanks again for your answer, it does seem the activity is being recreated every second or so in the Initialpreferences activity i have amended my question to include that code, if you wouldnt mind looking at it for me – J4C3N-14 Jul 25 '13 at 21:23
  • @J4C3N-14 I have edited my answer. I think the problem is that you are extending StartScreen in InitialPreference instead of Activity. I suggest you take a look to PreferenceActivity – AitorTheRed Jul 25 '13 at 21:36
  • You solved it thank you, I created the InitialPreferences activity using eclipse (does it for you). thank you very much, I will read into PreferenceActivity. cheers – J4C3N-14 Jul 26 '13 at 19:07
0

The correct way to stop a runnable is to terminate the loop inside it. In your case, there is no loop, so the runnable should just stop after getPreferences() finishes running.

Since you've placed it in onCreate, it will run 10000 ms after an activity is created or recreated

Oleksiy
  • 37,477
  • 22
  • 74
  • 122
  • Hi thanks for your answer, Unfortunately it doesn't seem to stop, the next activity gets loaded and then keeps loading every 10 seconds. Could this be down to the runnable being in onCreate? Can you give and example for me to remove it from onCreate. Thanks again, as you can tell im very muchly a novice at coding so please be patient. – J4C3N-14 Jul 23 '13 at 11:06
  • @J4C3N-14 1) name == "NAME" will always return false. You need to check for equality using syntax something like this: if (name.equals("NAME")) 2) You are getting exactly what you are doing - StartScreen activity will call InitialPreferences 10 sec after it's created. You probably have the same code in onCreate in your InitialPreferences activity. That would explain why it keeps calling itself over and over again. – Oleksiy Jul 23 '13 at 11:36
  • hi, thanks for your answer, i have replaced my code with yours as im sure that would be better but just out of curiosity, as part of fault finding with the code I removed the delay completely and it always worked fine either directing me to initialPreferences or mainActivity? In regards to the initialPreferences activity I dont have any delays set up in that activity if thats what you mean? – J4C3N-14 Jul 23 '13 at 19:54
0

Use Timer and TimerTask for repetitive task.

See below code. Its works for me.

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
  @Override
  public void run() {
      // use handler here.

  new Handler().postDelayed(new Runnable() {
      @Override
      public void run() { 
         getPreferences();
       }
     });
  }
},100000) // second parameter of scheduleAtFixedRate() method is Time in MilliSecond
             Specify the time interval here for repepititive execution.

In onDestroy or onStop Method of the Activity cancel the timer by using below code.

timer.cancel();
Jitesh Dalsaniya
  • 1,917
  • 3
  • 20
  • 36
  • Hi. I have seen your code before and tried it from someone else answer. It still results in the same problem I have but I will give it another go later as I may have missed something. Thanks – J4C3N-14 Jul 23 '13 at 11:19
0

Make your Runnable interrupt aware by handling interrupts and when you decide on cancelling/aborting Runnable instance send interrupt to it:

    run() {
    ..
      if(Thread.currentThread().isInterrupted()) {
         //thread is interrupt, abort run method, either by returning or throwing InterruptedException
         return;
         //OR
         throw new InterruptedException("Explicit abort signal!");
      }else {
         //continue your work
      }
   }

Generally interrupt flag is checked at multiple places inside run method (and in loops as well) as to make it more interrupt aware, you should add in getPreferences method at multiple points.

To interrupt a thread, caller may invoke t.interrupt where t is a Thread instance.

harsh
  • 7,502
  • 3
  • 31
  • 32