I want to study the Acitvity liftTimes ,then I have two Activities,called MainActivity and SecondActivity,and I set the launch mode to singleTask mode,the code below:
public class MainActivity extends Activity {
/** Called when the activity is first created. */
public static final String PREFS_NAME = "MyPrefsFile";
private TextView tv;
private Button bt;
private final static String TAG = "MainActivity";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG+"onCreate", "onCreate");
setContentView(R.layout.activity_main);
findViews();
tv.setText("MainActivity ID:" + this.toString());
bt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,
SecondActivity.class);
startActivity(intent);
}
});
}
private void findViews() {
// TODO Auto-generated method stub
tv = (TextView) findViewById(R.id.textView);
bt = (Button) findViewById(R.id.turnBt);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
Log.e(TAG+"onRestoreInstanceState", "onRestoreInstanceState");
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.e(TAG+"onRestart", "onRestart");
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.e(TAG+"onStart", "onStart");
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.e(TAG+"onResume", "onResume");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
Log.e(TAG+"onSaveInstanceState", "onSaveInstanceState");
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.e(TAG+"onPause", "onPause");
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.e(TAG+"onDestroy", "onDestroy");
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.e(TAG+"onStop", "onStop");
}
}
public class SecondActivity extends Activity{
private TextView tv;
private Button bt;
private final static String TAG = "SECONDACTIVITY";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreate");
setContentView(R.layout.second_layout);
findViews();
tv.setText("第二个界面的ID:"+this.toString());
bt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(SecondActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
private void findViews() {
// TODO Auto-generated method stub
tv = (TextView)findViewById(R.id.textView);
bt = (Button) findViewById(R.id.turnBt);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
Log.e(TAG, "onRestoreInstanceState");
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.e(TAG, "onRestart");
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.e(TAG, "onStart");
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.e(TAG, "onResume");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
Log.e(TAG, "onSaveInstanceState");
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.e(TAG, "onPause");
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.e(TAG, "onDestroy");
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.e(TAG, "onStop");
}
}
step 1:
launch MainActivity;
the logcat show below:
10-22 13:56:59.704: E/MainActivityonCreate(4649): onCreate
10-22 13:56:59.735: E/MainActivityonStart(4649): onStart
10-22 13:56:59.736: E/MainActivityonResume(4649): onResume
step 2:
from MainActivity to SecondActivity;
the logcat show below:
10-22 14:03:52.452: E/MainActivityonPause(4884): onPause
10-22 14:03:52.462: E/SECONDACTIVITY(4884): onCreate
10-22 14:03:52.485: E/SECONDACTIVITY(4884): onStart
10-22 14:03:52.485: E/SECONDACTIVITY(4884): onResume
10-2214:03:52.773:E/MainActivityonSaveInstanceState(4884): onSaveInstanceState
10-22 14:03:52.774: E/MainActivityonStop(4884): onStop
step 3:
from SecondActivity to MainActivity
the logcat show below:
10-22 14:05:14.561: E/SECONDACTIVITY(4884): onPause
10-22 14:05:14.574: E/MainActivityonCreate(4884): onCreate
10-22 14:05:14.592: E/MainActivityonStart(4884): onStart
10-22 14:05:14.593: E/MainActivityonResume(4884): onResume
10-22 14:05:14.877: E/SECONDACTIVITY(4884): onSaveInstanceState
10-22 14:05:14.877: E/SECONDACTIVITY(4884): onStop
step 4:
from MainActivity to SecondActivity
the logcat show below:
10-22 14:05:51.049: E/MainActivityonPause(4884): onPause
10-22 14:05:51.061: E/SECONDACTIVITY(4884): onRestart
10-22 14:05:51.061: E/SECONDACTIVITY(4884): onStart
10-22 14:05:51.061: E/SECONDACTIVITY(4884): onResume
10-22 14:05:51.330: E/MainActivityonStop(4884): onStop
10-22 14:05:51.330: E/MainActivityonDestroy(4884): onDestroy
my question:why the step 4,the MainActivity call the onDestroy() method ?
someone help me?
I tried your code and my onDestroy() Method does not gets called.
In your case onDestroy gets called i guess because system wants to clear some memory After your Step4 your backStack looks like below
Your back stack after method 4 is like this
SecondActivity Step 4
MainActivity Step 3
SecondActivity Step 2
MainActivity Step 1
According to developer website
onDestroy methods called
The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
As the system calls the stop method after that the destroy method is called for the activity and it's upto the device when to call the destroy method.
The stop method doesnot delete the memory of the activity on the device but the activity is not working anymore but as soon the destroy method is called all the memory allocation of the activity is destroyed.
Its totally dependent on device & # of running application. If you have a high end device (which has >1GB RAM; you probably will not see getting onDestroyed() called. That is because Android can keep more application running within more memory.
Again you can always force onDestroy() getting called by killing task from TaskManager. Alternatively you can set the developer option "Do not Keep activities" on ICS+ devices. This will always destroy your app whenever you leave it.
The main difference between onStop() and onDestroy() is that onStop() only suspends your Activity (UI & UI thread) but it does not touch your running threads (like network thread, Services, receivers e,g ). So, your app can still work (play music or download something) on background even if onStop() is called.
onDestroy() is called by android system to claim memory space (for new activity invoke or itself) and it will destroy the Activity which sits on the bottom of ActivityStack. You can think onDestroy() as a graceful shutdown request from system. You should stop everything if onDestroyed() called. After this call your every thread will be terminated.
Hope this helps, regards.
Related
I want to work on my data depending on what Lifecycle state I have.
For example, I want to do something, when the application was resumed.
How can I find out in what State is my app now?
Thanks for help.
in activity: if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) ... I think. If you're asking about async tasks.
For custom class you can use lifecycle from architecture components, first add library
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
then your custom class, for example
public class MyObserver implements LifecycleObserver {
#OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
...
}
#OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
...
}
}
and finally from your lifecycle container (activity/fragment)
myActivity.getLifecycle().addObserver(new MyObserver());
More info here https://developer.android.com/topic/libraries/architecture/lifecycle.html
There are predefined methods of an Activity.
Please review Life cycle of an Activity in Android.
Example code
public class LifeCycleActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toast.makeText(LifeCycleActivity.this,"ON CREATE", Toast.LENGTH_SHORT).show();
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Toast.makeText(LifeCycleActivity.this,"ON START", Toast.LENGTH_SHORT).show();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Toast.makeText(LifeCycleActivity.this,"ON RESUME", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Toast.makeText(LifeCycleActivity.this,"ON PAUSE", Toast.LENGTH_SHORT).show();
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Toast.makeText(LifeCycleActivity.this,"ON RESTART", Toast.LENGTH_SHORT).show();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Toast.makeText(LifeCycleActivity.this,"ON STOP", Toast.LENGTH_SHORT).show();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(LifeCycleActivity.this,"ON DESTROY", Toast.LENGTH_SHORT).show();
}
}
Also read: - https://developer.android.com/guide/components/activities/activity-lifecycle.html
Ok, this one is really tricky to me. The idea of this is a time log for EMS. You press a button by the action taken, and it logs the time for later use. I managed to figure out how to save the TextView into a string. Now, how on earth do I save the logTime1.setEnabled(false); so that on rotation or on leaving the activity, it restores it disabled? Eventually I will have another button beside it that will allow you to edit which will unlock the button. Here is the code.
public class TimeLog extends Activity{
boolean logTimeDis1=true;
Button logTime1;
String time1;
TextView ivTimeStamp;
int counter=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.time_log);
logTime1 = (Button) findViewById(R.id.logTime1);
ivTimeStamp = (TextView) findViewById(R.id.ivTimeStamp);
if(savedInstanceState != null) logTime1.setEnabled(savedInstanceState.getBoolean("logTimeDis1", true));
logTime1.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
time1 = new SimpleDateFormat("HH:mm", Locale.US).format(new Date());
ivTimeStamp.setText(time1);
logTime1.setEnabled(false);
logTimeDis1 = false;
return false;
}
});
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
counter++;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putString("ivTimeStamp", ivTimeStamp.getText().toString());
outState.putBoolean("logTimeDis1", logTimeDis1);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
ivTimeStamp.setText(savedInstanceState.getString("ivTimeStamp"));
}
}
So, in this line
if(savedInstanceState != null) logTime1.setEnabled(savedInstanceState.getBoolean("logTmeDis1", false));
you don't check if savedInstanceState contains logTmeDis1. Say, savedInstanceState is not null, but does not have logTmeDis1, you'll get false and your button locked. Actually, you don't have to check it in this case, just change false to true, and it should work correctly.
I was wondering, how can I keep the device listening for voice commands with voice recognition while the device is asleep? The idea I have is that I would like the device to respond to my voice, even if I have the screen locked or the screen has timed out.
Is this possible? I have tried using this as a service and an interface and it stops listening once the screen locks. Can I receive any help with this? This is my class.
public class VoiceEngineService extends Activity {
private boolean isSpeakingDone = false; // default setting
private SpeechRecognizer sr = SpeechRecognizer.createSpeechRecognizer(this);
private AudioManager mAudioManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.wait_for_speech);
// mute beep sound
mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);
sr.setRecognitionListener(new listener());
Intent i = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
i.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); // LANGUAGE_MODEL_WEB_SEARCH
i.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getApplication()
.getClass().getName());
i.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 6);
i.putExtra(RecognizerIntent.EXTRA_PROMPT, "");
i.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 5500);
sr.startListening(i);
}
class listener implements RecognitionListener {
#Override
public void onReadyForSpeech(Bundle params) {
// TODO Auto-generated method stub
}
#Override
public void onBeginningOfSpeech() {
// TODO Auto-generated method stub
}
#Override
public void onRmsChanged(float rmsdB) {
// TODO Auto-generated method stub
}
#Override
public void onBufferReceived(byte[] buffer) {
// TODO Auto-generated method stub
}
#Override
public void onEndOfSpeech() {
// TODO Auto-generated method stub
}
#Override
public void onError(int error) {
// TODO Auto-generated method stub
if (SharedPref.getVoiceController() == false) {
sr.cancel();
Intent i = new Intent();
sr.startListening(i);
} else {
sr.stopListening();
sr.destroy();
finish();
}
}
#Override
public void onResults(Bundle results) {
// TODO Auto-generated method stub
isSpeakingDone = true;
ArrayList<String> mDataList = results
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
Intent i = new Intent();
i.putStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS, mDataList);
setResult(RESULT_OK, i);
finish();
}
#Override
public void onPartialResults(Bundle partialResults) {
// TODO Auto-generated method stub
}
#Override
public void onEvent(int eventType, Bundle params) {
// TODO Auto-generated method stub
}
} // end listener class
#Override
protected void onPause() {
if ((isSpeakingDone == false)) {
finish();
}
super.onPause();
}
#Override
protected void onStop() {
// when speaking is true finish() has already been called
if (isSpeakingDone == false) {
finish();
}
super.onStop();
}
#Override
protected void onDestroy() {
sr.stopListening();
sr.destroy();
super.onDestroy();
}
}
You have to implement your voice listener in a service. Create a class that extends 'Service' and make up some logic to take care of recording.
If you tried already the service, then it might be that you tried to redirect commands to an activity which most likely has been stopped by Android OS. Generally when talking about doing stuff when phone is in lock mode, you only can hope to accomplish tasks in one or more services coupled togethe.
When you are in Activity, of course wen the activity goes out of scope it will be shut down by Android OS. but services can still run in background unless shut dow mm explicitly by your own code or in rare cases that Android will recognize that it needs memory and processor power for other tasks.
Guys I am stuck in a problem with these two methods:-
When I change the orientation of device and set the text in edit text after retriving the text from bundle,it does't work.But the same code is working in onrestoreStoreInstante method.
Please have a look at my code:-
public class LifeCycleActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
EditText user;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
user=(EditText)findViewById(R.id.et_user);
if(savedInstanceState!=null){
String s =savedInstanceState.get("Key").toString();
user=(EditText)findViewById(R.id.et_user);
user.setText(savedInstanceState.get("Key").toString());
Toast.makeText(this, s,Toast.LENGTH_SHORT).show();
}
Toast.makeText(this, "onCreate",Toast.LENGTH_SHORT).show();
Button b=(Button)findViewById(R.id.button1);
b.setOnClickListener(this);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Toast.makeText(this, "onSaveInstanceState",Toast.LENGTH_SHORT).show();
outState.putString("Key", "Deepak");
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//String s =savedInstanceState.get("Key").toString();
//user.setText(s);
Toast.makeText(this, "onRestoreInstanceState",Toast.LENGTH_SHORT).show();
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Toast.makeText(this, "onStart",Toast.LENGTH_SHORT).show();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Toast.makeText(this, "onResume",Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Toast.makeText(this, "onPause",Toast.LENGTH_SHORT).show();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Toast.makeText(this, "onStop",Toast.LENGTH_SHORT).show();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "onDEstroy",Toast.LENGTH_SHORT).show();
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Toast.makeText(this, "onRestart",Toast.LENGTH_SHORT).show();
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(LifeCycleActivity.this,SecondActivity.class));
}
}
when I set the text in edit text in oncreate method after getting the value from Bundle,it doesn't work.But the same code works in onRestoreInstanceState() method.
According to me , it should work for oncreate also as we can get the Bundle class object there.
Please help me to sort out this problem..
EditText and most of other views have their own methods to save/restore their own data. So in general it's not necessary to save/restore them on your code.
You can see this here on the Android TextView source code (remember that EditText extends from TextView) on line 3546:
if (ss.text != null) {
setText(ss.text);
}
so the reason you can't set it onCreate and can do it onRestoreInstanceState it's because during your activity super.onRestoreInstanceState(savedInstanceState) the activity calls the EditText.onRestoreInstanceState and the EditText restore it self to the previous value.
You can see it happening on the Activity source code on line 940
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (mWindow != null) {
Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
if (windowState != null) {
mWindow.restoreHierarchyState(windowState);
}
}
}
hope it helps.
Overview
onSaveInstanceState() is used to put the data to bundle
onRestoreInstanceState() is used to set the data available in
bundle to your activity
So do as follows:
i Guess until the activity is created onorientation change the
bundle is not available, that's way you are not able to retrieve it
in oncreate
Let the activity create in oncreate
Then restore the instance in onRestoreInstanceState
Hope this helps !
i have a simple activity where i start a service in onCreate depending on checkbox state.
#Override
protected void onCreate(Bundle savedInstanceState) {
if(savedInstanceState == null)
Log.e(TAG,"savedInstanceState is null");
if(savedInstanceState != null){
Log.e(TAG,"savedInstanceState is not null");
}
super.onCreate(savedInstanceState);
on checkbox state checked starting the service and setting serviceStarted
toggleButton1.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked){
Log.e(TAG,"starting service");
serviceStarted = true;
startService(new Intent(getApplicationContext(), MyService.class));
}else{
serviceStarted = false;
stopService(new Intent(getApplicationContext(), MyService.class));
}
}
});
i have overrided below functions
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
Log.e(TAG,"onSaveInstanceState called");
super.onSaveInstanceState(outState);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.e(TAG,"onResume called : serviceStarted = "+String.valueOf(serviceStarted));
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.e(TAG,"onPause called : serviceStarted = "+String.valueOf(serviceStarted));
}
Now in my logcat, on minimize and re-launching the app after starting service, i see below
04-22 12:34:42.150: E/MainActivity(19720): onPause called : serviceStarted = true
04-22 12:34:44.700: E/MainActivity(19720): onResume called : serviceStarted = false
Now my need is
I want to preserve state of serviceStarted without using sharedpreferences
Anyway there, or should i go with service binding model ? Please help Thank you
Well, just use the whole save instance state thing, that's what it's for:
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("serviceStarted", mServiceStarted);
}
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
mServiceStarted = state.getBoolean("serviceStarted", false);
}
But actually, if your activity gets destroyed for reals (by back button or by the OS), you'll still lose state, so the more reliable option is to use SharedPreferences.
But in your case, service can still get killed between the times your activity pauses and gets brought back -- then your serviceStarted will be obsolete. So just use a static member to know the state:
public MyService extends Service {
private static volatile boolean mIsRunning = false;
public void onCreate() {
MyService.mIsRunning = true;
}
public void onDestroy() {
MyService.mIsRunning = false;
}
public static boolean isRunning() {
return mIsRunning;
}
}