Reputation: 696
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);
}
}
Upvotes: 1
Views: 2731
Reputation: 553
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
Upvotes: 1
Reputation: 7692
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.
Upvotes: 0
Reputation: 1917
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();
Upvotes: 0
Reputation: 39800
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
Upvotes: 0