I am updating the local database in onDestroy() of activity A. Activity B is depends on the local DB which is updated in onDestroy() of activity A.
My problem is that whenever I start Activity B and finish Activity A onDestroy() of activity A is being called after onCreate() of Activity B. Due to this issue I am losing the data stored after destroying Activity A.
How do I fix this issue?
Activity A
#Override
protected void onCreate(Bundle savedInstanceState){
//After retrieving User data
//inside onclicklistener
someButton.setOnClickLister( new View.OnClickListener() {
public void onClick(View view) {
finish();
startActivity(this,FamilyInfoActivity.class);
}
}
}
#Override
protected void onDestroy(){
localJson.setStatus(status);
localDBUtil.setLocalJson(this,localJson,connectionId);
super.OnDestroy();
}
Activity B
#Override
protected void onCreate(Bundle savedInstanceState){
localJson = localDBUtil.getLocalJson(this,connectionId);
}
You cannot rely on the timing of onDestroy() to save your changes. You should save changes in onPause() which is the only lifecycle method that is guaranteed to be called.
Also, if you want to pass data from ActivityA to ActivityB, you can use one of the following methods:
Store data in a file
Store data in an SQLite database
Store data in SharedPreferences
Put the data in "extras" in the Intent you use to launch ActivityB (only if the amount of data is not too large)
Please remove finish() in onCreate. Finish is destroying your Activity that's why onDestroy is being called
Related
I'm building an app that plays music on the background with service. The music is muted when the user is not in the app and unmuted when he is back. I used the onPause() and onResume() methods to do this.
The problem is - every time the user enters a new activity, the music pauses for a second and then resumes, because for a second the current activity is paused.
another problem - for the first run of the activity, the onResume() and onCreate() both works, which makes my service stops from the onResume() without it even being created from the onCreate() (which makes the app shut down).
is there a way to use onPause() without the intent part (or another similar way?)
is there a way to use onCreate() without to onResume() on the first run?
protected void onCreate(Bundle savedInstanceState) {
counter++;
if (counter==1) {
alliesSPEditor.putBoolean("isAllies", true);
alliesSPEditor.commit();
startService(new Intent(this,MusicService.class));
}
#Override
protected void onPause() {
super.onPause();
MusicService.getMP().mute();
}
#Override
protected void onResume() {
super.onResume();
if (counter!=1) //because the counter is still 1, the app won't shut down this way but it will not unmute the music.
MusicService.getMP().unMute();
}
onResume() is always called after onCreate() before the activity starts running
See https://developer.android.com/guide/components/activities/activity-lifecycle
I see some ways to solve this:
the problem is - every time the user enters a new activity, the music pauses for a second and then resumes, because for a second the current activity is paused
The first is you set a flag in the handler that start your new activity and
check in your onPause() method the value of de flag, if false, do nothing othewise mute de music.
public static boolean openOtherActivity = false;
#Override
protected void onPause() {
super.onPause();
if (!openOtherActivity) {
MusicService.getMP().mute();
}
}
You can use Preferences too if you preferrer
To resolve de onCreate() and onResume() problem, you can use the same logic
creates a flag for the services started and control when you needs unmute the music in anothers methods
public static boolean isServiceCreated = false; // In your activity that start the service
protected void onCreate(Bundle savedInstanceState) {
counter++;
if (counter==1) {
alliesSPEditor.putBoolean("isAllies", true);
alliesSPEditor.commit();
startService(new Intent(this,MusicService.class));
isServiceCreated = true; // set the flag to true
}
}
OnResume() method you can check if the service is started an create your logic
What should I do to prevent activity from being destroyed when home button is pressed. My activity is destroyed by pressing home Randomly.
Thanks in advance
This is the activity lifecycle-
When any application's activity goes to the background after the Home button was pressed, it isn't destroyed arbitrarily - the OS destroys activities in the background when it runs short of available RAM, so when the Home button is pressed the activity goes to onPause() -> onStop() and then it's up to the OS's mercy.
This can happen to any device running Android OS which runs into a low memory scenario at any given time, not only Galaxy S3.
The way to handle this is to use onSaveInstanceState in your activity:
#Override
protected void onSaveInstanceState(Bundle outState) {
// Put all important data you have into the outState before calling
// super.
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
// Here you will receive the bundle you put in onSaveInstanceState
// and you can take it from the state bundle and put it in place.
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Here you need to check if you have data, if
// onSaveInstanceState was called and you put data in that
// function, data should be available here, and put it back into
// place.
}
Here is the following scenario:
Filling the EditText and other Fields in Activity A
Moving from Activity A to Activity B on Buttonclick
Now Moving from Activity B to Activity A on Button Click
populated EditText is gone now. They are all empty
These fields should be pre-populated (as user has already filled them)
Is there any way to save the current state of Activity A. So that I can populated the EditText back? If not then How can I achieve the above task?
Use SharedPreferences.Editor to save the EditText data onPause, and retrieve the data with SharedPreferences onResume. That's the easiest way.
How are you moving from b back to a? If youre using an intent then your starting a new instance of that 'a' activity. Like some one mentioned above you should be using finish in your b activity which would take you back to a. If you need to populate a with data from b then you should use startActivityForResult - http://developer.android.com/training/basics/intents/result.html
To save the activity state, override OnSaveInstanceState() method.
#Override
protected void onSaveInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("key", somevalue); //save your data in key-value pair
}
and restore the value using,
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
somevalue = savedInstanceState.getString("key");
}
Use this method if you are destroying the activity and creating it again.
I want to refresh fragments from an Actvitiy. (Let's call the activity A)
Activity A contains the fragments.
When I finish Activity B then Activity A should refresh the fragments.
I was thinking this would be done in onResume? I tried simply restarting the activity through an intent but that's not usability friendly.
So how do I refresh fragments when I resume an activity?
Just put this code inside
onResume()
For example you want to update your listview when u return to your fregment.
#Override
public void onResume() {
super.onResume();
if (allowRefresh)
{
allowRefresh = false;
lst_applist = db.load_apps();
getFragmentManager().beginTransaction().detach(this).attach(this).commit();
}
}
Here getFragmentManager().beginTransaction().detach(this).attach(this).commit();
This line detach and re-attach the fragment so your content will be updated.
The onResume() get called always before the fragment is displayed. Even when the fragment is created for the first time . So you can simply move your from onViewCreated() to onResume.
#Override
public void onResume() {
super.onResume();
//move your code from onViewCreated() here
}
I agree with Mehul But u can alse do it this way .if you want to replace your fragment you could just say
#Override
public void onResume() {
super.onResume();
if (allowRefresh)
{
allowRefresh = false;
lst_applist = db.load_apps();
getFragmentManager().beginTransaction().replace(Fragment_Container,fragment).commit();
}
}
I'm starting a project and I want to reproduce a video in the main activity when the app is executed, when the user presses the video it goes to another activity. If the user press the back button, he is going to the main screen again and reproduces the video from the beginning. The video is located in the raw directory.
The problem is that the videoview is reproducing the video when the activity is first created but not when the user goes back to it from the other activity (In my case the MenuSection activity). The code is really simple but i will paste it anyway:
public class MainActivity extends Activity {
private VideoView mVideoView;
LinearLayout menuSection;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
mVideoView = (VideoView) findViewById(R.id.surface_view);
mVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() +"/"+R.raw.documentariesandyou));
mVideoView.requestFocus();
mVideoView.setMediaController(null); //i dont want the controls of the videoview.
mVideoView.start();
menuSection = (LinearLayout) findViewById(R.id.menuSection);
menuSection.setOnClickListener(new menuSectionListener());
}
class menuSectionListener implements OnClickListener {
public void onClick(View v) {
Intent staticActivityIntent = new Intent(MainActivity.this, MenuSection.class);
startActivity(staticActivityIntent);
}
}
}
The MenuSection is just an activity that shows a textview like "Hello world", so I'm not pasting it.
Move mVideoView.start(); to onResume() instead of onCreate() as:
#Override
protected void onResume() {
super.onResume();
mVideoView.start();
}
see Managing the Activity Lifecycle onResume() is called from your Activity when Activity is Already Running
call video.pause() on onPause() overrided method of your activity and call video.resume() on onResume() method of your activity.
Move mVideoView.start(); to onStart(), instead of onCreate().
See Activity Lifecycle in the developer docs for more info on how the lifecycle of Activities work.
I am not certain, but you may also need to move the setVideoURI(); to onStart() as well.