Multiple classes, onCreate saved instance issue - android

Ok, so quick explanation. I have an app that consists of 3 files.
Main.java, License.java ,App.java
For an example. This app does function 100% except for what i am about to ask. This app does contain a webview and in here lays the issue. I have researched and most everything points to orientation changes. I am not having a problem with orientation because i force landscape at the moment. I am having an issue with the phone going to sleep.
When it wakes, it reloads the page inside the webview. I can add a lock for that, but if someone manually locks their phone, then unlocks it, it will be the same response. Or can you manually lock it if the force wake is in the app? Guess i need to test that one.
Anyways, i am guessing the saveinstancestate will remember the location in the webview and reload to it? If so, which of the oncreates does it go in?
Main is launched when it first opens, this one calls the license, if it passes it then opens the application

Do you do anything special on onPause and onResume? When the phone goes to sleep, as far as I know only onPause should be called, and when woken up onResume. Maybe you load the webview content in onResume?
Also, if you want to share some data amongst your activities, you could try using an Application context instead. I.e. in the AndroidManifest file define a class to be used as application (just like you do with activities, with the "android:name" attribute). The class of course should be a sub-class of "android.app.Application".
See also:
http://developer.android.com/guide/topics/manifest/application-element.html
http://developer.android.com/reference/android/app/Application.html

Related

How to continue on the last activity when the app is closed and started again?

So, for my Android course this semester we're making an app of our own choosing, and due to a lack of ideas I decided to go with a text-adventure styled game. Nothing too complicated, I know. I'm making sure to be creative and incorporate a lot of different functions of the phone, such as the accelerometer and the camera. But I digress.
I've started planning out how the app should work, and how I should go about coding it, but I've come upon an obstacle fairly early that I need to find a solution for. I'm planning on creating it so that the player is sent from activity to activity, which I think is the best way to go about it, unless I do an endlessly scrolling activity that fills out as the player progresses. And thus, I need a way to make it so that when the player closes the app completely it will "continue" on the last activity before shutdown, so the progress is saved in a way.
I'm not sure if this is possible to do, and if so, are there any other ways I can achieve the same sort of result?
There is no way that you can change your starting activity programmatically. You can save the activity that you want to start with in a file and redirect to this activity from your main activity every time your application starts (on the onCreate() method of your main activity).
As it says here.
As someone has suggested, save the current state (ie: what Activity is currently shown) in SharedPreferences. When the user launches your app, the root Activity (the one with ACTION=MAIN and CATEGORY=LAUNCHER) will be started. In onCreate() of the root Activity, read the saved state from the SharedPreferences and launch that Activity immediately.

Simulate Activity/Fragment re creation

I am trying to simulate Activity and Fragment re-creation and also to check onSaveInstancestate() and onRestoreInstanceState() and generally so check if I am handling activity re-creation in a good way in all cases, for example, just like when screen rotation causing the activity to re-create it self.
But in my case I want to check more options/cases which can cause re-creation because my app cannot be rotate(all activities are in portrait).
I saw many articles, blogs and stackoverflow question/answers about this topic, for example here, here, and here.
And as this stackoverflow answers says Why not use always android:configChanges="keyboardHidden|orientation"?
there are many more events which can cause activity re-creation, so after I read it I wanted to test my app for some of those events.
For example I pressed the home button in my activity and then I went into settings and tried to change the language, change the font size , etc... , but non of those actions made my app re-create as I would expect.
When I returned to my app , it just resumed and onCreate() never called.
So I even check the official documents about this. and they also says that it should cause my activity to re-create: Quoting:
"When a configuration change occurs at runtime, the activity is shut down and restarted by default"
but as I said it didn't happen to me.
This is I huge for me because I was very naïve and thought that if my app will be only in portrait or if I will add to the manifest this line :
android:configChanges="keyboardHidden|orientation|screenSize"
then every thing will be ok and obviously its not because there are many more configurations changes which can restart my activity, so I can't run from it anymore and I want to handle it in a good manner and now I want to also test it.
Changing the device language is one way to force re-creation of all activities that doesn't involve orientation change.
You said that it wasn't being recreated when you change the orientation of your device while in the app. Normally it would. When you added the lines android:configChanges="orientation" it means that you're telling the system you will deal with orientation changes in your app and not to worry about the normal behaviour.
If you remove that from your activity declaration in the manifest, you'll see it operating as expected (destroying/recreating on orientation change).
Hope that helps.
Pressing the home button will only initially cause onPause to be raised. Your Activity will not go through onCreate again until it has been fully destroyed, which won't happen unless Android decides it needs the memory for other processes.
The easiest way is just to remove orientation from configChanges and then rotate your Activity and see what happens. The layouts might not work correctly, but your should be able to inspect your lifecycle code. Similarly, remove keyboardHidden and then toggle the soft keyboard. Your Activity should go through the lifecycle sequence.
Changing the locale for the device should cause your Activity to be recreated. Note that this is the global locale that needs to be changed, not the language the keyboard is typing in.
Other ways come to mind such as manually destroying the app either via a key sequence on the phone (for example, holding down the Home button and swiping left on the app to kill on some phones), or by terminating it from your debugger.
On your device/emulator Developer Options, activate the option:
"Don't keep activities".
With it on, anytime the activity is paused and returned the cycle for saved instance is called (e.g. another activity in front of it or home button pressed to minimize all apps, ...). It's useful to test and simulate recreation and related bugs.

How to resume Android app where it was suspended (app not Activity)

How can I have my Android app resume where it last was, i.e. the Activity in view, etc.? If I am showing an Activity and press the Home button and then launch my app again it returns to the startup activity. I'd like it to work like an iPhone app where it suspends in place and resumes back to where the user last was.
Thank you.
You may need to set android:alwaysRetainTaskState="true" for your root activity in the manifest. From the documentation:
Whether or not the state of the task
that the activity is in will always be
maintained by the system — "true" if
it will be, and "false" if the system
is allowed to reset the task to its
initial state in certain situations.
The default value is "false". This
attribute is meaningful only for the
root activity of a task; it's ignored
for all other activities.
Normally,
the system clears a task (removes all
activities from the stack above the
root activity) in certain situations
when the user re-selects that task
from the home screen. Typically, this
is done if the user hasn't visited the
task for a certain amount of time,
such as 30 minutes.
However, when this
attribute is "true", users will always
return to the task in its last state,
regardless of how they get there. This
is useful, for example, in an
application like the web browser where
there is a lot of state (such as
multiple open tabs) that users would
not like to lose.
Be sure to save any information you want in your onPause method and check that information in onResume. This will let the app reload any information that was communicated. Some widgets keep state but others don't.
Additionally when an an activity is killed it's onSaveInstanceState method is called. So anything that needs to be stored to persistent memory should be done there.
Although i'm working with Mono for Android i had a similar question.
After some time researching on the web you can setup an Activity to be created using the singleton pattern. This will cause your app to only create one instance and - if you go back to the activity - this will load the last state of that activity for you.
You can do this by configuring the activity with the
android:alwaysRetainTaskState="true"
and the
android:launchMode="singleTask" //(preffered, or "singleInstance")
properties.
Singletask is the best since singleInstance is more suitable for single-activity-based apps.
In my case setting the launchmode made this baby rock as i wanted but i don't know if this is a Mono for Android or Android issue at the root..
Be aware: you will need to create an initialize method or something alike if you'd like to create a clean/fresh/new instance of the activity at some point.

How should I deal with persisting an Android WebView if my activity gets destroyed while showing another one?

I'm building an Android application that's based around an enhanced WebView (based on PhoneGap). I've enhanced the WebView so that from JavaScript running inside you can invoke the native contact picker to choose a phone number (which may be supplied by Facebook for example).
The problem I have is that the native contact picker runs in an activity in another process and the Android docs say that while another activity is open my activity may get destroyed due to memory constraints. I haven't actually seen this happen in my application but if it did then I'm guessing my WebView's state would be destroyed and the code that was waiting for the picked contact would be terminated.
It seems a bit crazy that the activity requesting a contact could be destroyed while the contact picker is open. Does anyone know if that does indeed happen? Is there a way to persist the state of the WebView if it does?
Thanks,
-Shaun
Does anyone know if that does indeed
happen?
You're looking at the problem too simply.
You have a WebView. You open the contacts application. While the user is in the contacts application, a phone call comes in. While on the phone call (using a Bluetooth headset), a text message comes in, so the user opens that up from its Notification. While still on the phone call and texting away, a text comes in with a link, so she taps it and brings up the Browser application.
By this time, your activity is surely destroyed, except on maybe some of the most recent phones that have a fair bit of RAM.
Now, is that common? No. However, this also has nothing to do with the contacts application -- if the user presses HOME, at some point in the future, your activity may be destroyed to free up RAM as well.
Is there a way to persist the state of
the WebView if it does?
That depends on what you consider "the state of the WebView" to be. This really is PhoneGap's job, if you are making a PhoneGap-based app. So, you might consider asking them.
There is no way to persist the DOM. There are trivial ways to persist the URL (see onSaveInstanceState()). And there may be stuff in between that you consider part of "the state of the WebView" that may or may not be possible to save.
The long and detailed answer is a bit complicated, but essentially it comes down to a few points:
If the Android OS has to go cleaning up Activities or Services, it knows how to prioritise which ones should go first. It does this based on whether they're currently in the foreground (last to go), in the middle of executing code, waiting for a result, or simply sitting inactive in the background (first to go). You can be reasonably certain that if your WebView Activity launched the contact picker using the startActivityForResult, it won't be killed
There's a whole system for saving data if an activity is killed, such as the onPause method (which are triggered as soon as your activity leaves the foreground), the onSaveInstanceState method which is called when your activity is about to die. Read up on those to get more information, and the configurationChanged method when the screen orientation changes. If you haven't at least skim read the Activity Lifecycle document on the developers page, you must do that.
Lastly, I'm sure this question has been addressed many times, but with slightly varying wording or situations. Have a look around, see what else you can find.

Android: Determine when an app is being finalized vs destroyed for screen orientation change

I am relatively new to the Android world and am having some difficultly understanding how the whole screen orientation cycle works. I understand that when the orientation changes from portrait to landscape or vice versa the activity is destroyed and then re-created. Thus all the code in the onCreate function will run again. So here's my situation: I have an app that I am working on where it logs into a website, retrieves data, and displays it to the user. While this is all done in background threads, the code that starts these threads is in the onCreate function. Now, the problem lies in that whenever the user changes the screen orientation, the app will log in, retrieve the data, and display it to the user again. What I would like to do is set a boolean that tells the app if it is logged in or not so it knows whether or not it must log in when the onCreate function is called. So long as the app is in memory the HttpClient will exist and contain the cookies from logging the user in but when the app is killed by the system those will go away. So I would assume that I need to do something like setting the logged in boolean to false when the app is killed but since onDestroy is called when the screen is rotated how is this possible? I also looked into the finalize function and isFinishing() but those seem to not be working.
Shorter version: How can I distinguish between when an app is being killed from memory from when an activity is being rotated and different code for each event?
Any help or a point in the right direction is greatly appreciated. Thank you!
Matt, you need to tell the platform that your activity can handle orientation changes so that there's no need to restart it.
To do this, add android:configChanges="keyboardHidden|orientation" to activity declaration in AndroidManifest.xml. More info here.
As alex pointed out you can tell android to not restart your activity when doing orientation changes... When you have to restart your application (maybe screen orientation changes your render context etc...) you can get informed of the changes by overriding onConfigurationChanged(..) in your Activity.

Categories

Resources