I'am having troubles with Googles MapView Activity.
The reason for my problem:
My application relies on many asynchronous events. When I start an Activity containing the Map, I've a template mechanism which adds and initializes the Map and relays all activity callbacks like onCreate(), onResume() to the map. All works fine!
But when this activity is restored from background my template mechanism is not yet ready to create the dynamic layout in onCreate(), hence I can't relay the lifecycle callbacks which are needed for the Map. In worst case, the Map is created after onResume().
This simplified code is for understanding the issue:
public class MapActivity{
List<Templates> templates;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (app.isInit())) {
initActivity();
}
templates.onCreate();
}
// init after templates are loaded
private void initActivity() {
templates = templateEngine.renderSomeTemplates()
}
#Override
protected void onResume() {
super.onResume();
templates.onResume()
}
public void onEventMainThread(InitAppEvent event) {
initActivity()
}
}
So my question.
Is there any way to add a google MapView programmatically during runtime without passing onCreate() and so on to it or do some lazy init?
Ok, I figured it out.
Apparently it's impossible to live without the callbacks as described in the docs:
http://developer.android.com/reference/com/google/android/gms/maps/MapView.html
So I found a trick to force my activity to start all over again, as soon as my dependencies (templates) are ready.
If anyone is looking for a neat way to restart an activity: there is recreate()
http://developer.android.com/reference/android/app/Activity.html#recreate()
It basically finishes the activity and repeats the normal lifecycle from the beginning.
Yes its is possible, take a look at the samples in the SDK
Related
Official documentation about Activity lists out 7 life cycle methods.
onPostResume() was not quoted as life cycle method.
But I feel that this method is important method.
During the life cycle, when an activity is visible from hidden to show state,
onRestart()
onStart()
onResume()
onPostResume()
have been invoked in order.
My code snippet:
package ravindra.projects.my_app_1;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private EditText txtUserName;
private EditText txtPassword;
Button loginButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("Ravi","Main OnCreate");
txtUserName=(EditText) findViewById(R.id.username);
txtPassword=(EditText) findViewById(R.id.password);
loginButton = (Button) findViewById(R.id.login);
loginButton.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Log.d("Ravi", "Login processing initiated");
Intent intent = new Intent(this,LoginActivity.class);
Bundle bundle = new Bundle();
bundle.putString("userName",txtUserName.getText().toString());
bundle.putString("password",txtPassword.getText().toString());
intent.putExtras(bundle);
startActivityForResult(intent,1);
// IntentFilter
}
public void onActivityResult(int requestCode, int resultCode, Intent resIntent){
Log.d("Ravi back result:", "start");
String result = resIntent.getStringExtra("result");
Log.d("Ravi back result:", result);
TextView txtView = (TextView)findViewById(R.id.txtView);
txtView.setText(result);
}
#Override
protected void onStart() {
super.onStart();
Log.d("Ravi","Main Start");
}
#Override
protected void onRestart() {
super.onRestart();
Log.d("Ravi","Main ReStart");
}
#Override
protected void onPause() {
super.onPause();
Log.d("Ravi","Main Pause");
}
#Override
protected void onResume() {
super.onResume();
Log.d("Ravi","Main Resume");
}
#Override
protected void onStop() {
super.onStop();
Log.d("Ravi","Main Stop");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d("Ravi","Main OnDestroy");
}
#Override
protected void onPostResume() {
super.onPostResume();
Log.d("Ravi","Main PostResume");
}
#Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
}
Implementing onPostResume() by skipping below methods doesn't serve the purpose?
onRestart(), onStart(), onResume()
What are the advantages of implementing these three methods if I implement onPostResume() ?
onRestart(), onStart(), onResume()
onPostResume :
Called when activity resume is complete (after activity's {#link #onResume} has
been called). Applications will generally not implement this method;
it is intended for system classes to do final setup after application
resume code has run.
It will do following things
It will ensure that screen is visible to user and will do the final
set up for activity.
Remove any pending posts of messages with code 'what' that are in
the
message queue.
Check all fragment gets resumed and Moves all Fragments managed by
the controller's FragmentManager into the resume state.
Execute any pending actions for the Fragments managed by the
controller's FragmentManager.
If you check it life cycle vise it worked like below
onResume() - Activity
onResume() - Fragment check third point as explained above
onPostResume() - Activity
onPostResume is mainly reserved for system actions which want to finish some kind of setup after any subclasses have finished resuming.
The two things it is good for, (which might make you feel it's important) are for doing actions after your nested fragments are also resumed and when the applications is guaranteed to be visible to the user (it may not yet be visible during onResume).
It can be a little confusing from the method names when looking at the Sources, but if you log the flow you'll see what happens is
Activity Resumes
Fragment Resumes
onPostResume is called in Activity
I will add a word of caution for any future readers - if you use onPostResume to wait for your fragment, to call some get method (for example), then you have a bad, unreliable design. You should instead have a callback pattern from your fragment and have the fragment "send" the data back to the activity when it is ready
Before answering your question lets talk about onPostResume()
According to android
onPostResume()
added in API level 1
void onPostResume ()
Called when activity resume is complete (after onResume() has been called). Applications will generally not implement this method; it is intended for system classes to do final setup after application resume code has run.
So as they said it is called once the activity is resumed. So if you want to do something after an activity is resumed you can use this method. But mostly we do all the stuff in onResume() like begin animations, open exclusive-access devices (such as the camera), etc. so once Activity is resumed onPostResumed() get called. So don't you think it differs from on resume? Because in onPostResume() according to os activity is already resumed.And for the onPause and onStop().They are different. They are when an activity is going into the background but has not (yet) been killed and Called when you are no longer visible to the user respectively. So they are different from onResume() and onPostResume().
Now before relying on onPostResume() you should read these two things
As far as developers.android
1 - Applications will generally not implement this method; it is intended for system classes to do final setup after application resume code has run.
(But we can use it for our purpose no matter what the intent of this).
2 - Check this link . He said that onPostResume() is not ALWAYS called . And his case was for fragments ( Of course they are over an activity man ).
Here is the reply,
The issue is completely resolved in API level 16 and support library rev 9.
New method "FragmentActivity.onResumeFragments()" should be used.
So some of them having issues in relying on this method so it's up to you know.
onPostResume() was not quoted as life cycle method.
But I feel that this method is important method.
Most probably your feelings are wrong. And my answer on why it is so is a bit long and kind of abstract.
Abstract (but important) part
Typically various onPreXyz and onPostXyz (aka onBeforeXyz and onAfterXyz) methods are an attempt to make a base class open to extension by subclasses but still preserving some important behavior aspects. Assume that you are designing you own base class and you have a lifecycle event "Xyz" and your default handling behavior is following:
Do some initialization before any other handling
Do actual handling of event including customizable logic
When all customizable handling is done do some finishing logic
Now assume that you are making something like Activity class - a base class with some bits of logic and the one that would be heavily inherited from, probably with deep hierarchies of inheritance. Now you should think of where (when) sub-classes logic will be exectuted regarding to logic in your base class. The important tricky part here is that you want your sub-classes to put their additional logic around step #2 (i.e. after #1 and before #3). You can't easily achieve this goal with simple virtual method because subclass can either put their logic after call to super which is after #3 or (rarely) before super call i.e. before #1. So what would you do? The Template method pattern comes to the rescue. You orgainze you code in a following way
class Activity {
public final void performXyz(XyzEventData eventData) {
onPreXyz(eventData);
onXyz(eventData);
onPostXyz(eventData);
}
protected void onPreXyz(XyzEventData eventData) {
// put you logic from step #1 here
}
protected void onXyz(XyzEventData eventData) {
// put you logic from step #2 here
}
protected void onPostXyz(XyzEventData eventData) {
// put you logic from step #3 here
}
}
So you have single external entry point performXyz that is called by the whatever context generates lifecycle events when the Xyz event happens and it dispatches the event internally to 3 different methods enforcing some sequence of execution. Typically you put all your code in your subclasses inside the "main" onXyz method unless you have a good reason to put it in one of the two others i.e. you expect your class to be subclassed as well and you want to ensure some execution order.
There are a few more points worth noting:
Entry-point method performXyz is final (i.e. non-virtual). In this way you ensure that nobody can override it and break your execution order enforcement logic.
The base class might even leave onPreXyz and onPostXyz
methods empty by putting its steps #1 and #3 logic directly into performXyz. But if the designer of the base class expects possible deep inheritance hierarchies where some intermediate sub-class, that will be a base class for many other deeper subclasses (such as Layer supertype), might need the same execution order enforcement feature, it makes sense to provide such methods in the base class anyway.
One of the onPreXyz or onPostXyz method might be
omitted altogether if your case doesn't require 3-steps execution
separation and 2-steps are enough. This is what often happens in Android: there are much more onPostXyz methods than onPreXyz but AsyncTask seems to be one noticible exception that feature both of them.
Closer look at Android (and onPostResume)
So after this long introduction, how Android uses this approach for onPostResume? If you look at the code at Activity.onPostResume you'll notice that it does very few things in the base class and the ones that are tightly related to UI stuff and probably expect all data-structures to be fully ready. This of course is not very surprising.
What is more interesting is how it is used in the subclasses. One of the very few overrides is at FragmentActivity from the v4 support library which provides backported "Fragments" features for old devices. FragmentActivity.onPostResume contains logic to resume child fragments. You may notice that in the standard Activity class similar logic to resume fragments is put directly into performResume method between mInstrumentation.callActivityOnResume(this); and onPostResume(); calls so it seems to be a part of step #3 in my earlier abstract description just put into the caller code. Obviously FragmentActivity can't put any new code to the Activity.performResume to ensure that it will be executed after activity's resume is done. Thus it puts the logic to the overridden FragmentActivity.onPostResume and in this way preserves the same semantics that fragments should be resumed after activity has already been resumed. Note also that the fact that this semantics explicitly preserved in both Activity and FragmentActivity classes suggests that this is the way it better should be. So if your code actually uses fragments, you'd better not put extensive logic into your onPostResume or something bad might happen (not sure what exactly).
After using log and overriding methods of activity lifecycle I came to following conclusion:
This method can be very help ful in case you want to do execute any particular task in parent activity efter resuming a fragment (after loading a fragment) ....
I used/tried following code snippets to get to this conclusion :
in Parent activity :
//postResumemethod
#Override
protected void onPostResume() {
super.onPostResume();
Log.v("testPostResume","reached_postResume") ;
}
In called Fragment :
//On ResumeMethod
#Override
public void onResume() {
super.onResume();
Log.v("testStartFragment","reached_Startfragment") ;
}
This is my Log :
V/testStartFragment: reached_Startfragment
V/testPostResume: reached_postResume
We can clearly see the post resume is called after the onResume method of Fragment is executed . So after calling/loading fragment if you want to execute any code in activity(any task through acivity after loading fragment ) you can do that
I hope this clarifies the query
I'm working on my 1st Android app and wondering how to handle activation/deactivation/starting/stopping globally, not on Activity level.
This great article shows states transition for Activities:
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Is there something similar for Application states?
For example at iOS and Windows Phone app there is clear app states separated from activities (views, controllers, whatever).
I'm asking because I want to perform certain operations only once per app loading/exiting not with every activity starting/stopping
The answer is There is Simply No Direct method to do this
rather than in Application Class you can catch these events
#Override
public void onLowMemory()
{
super.onLowMemory();
}
#Override
public void onTerminate()
{
super.onTerminate();
}
So you will have to handle it in all the Activities you will be having
the following methods
onResume()
onStart()
onRestart()
onPause()
onDestroy()
You will have to implement in all Activity to handle for all application
A suggesstion
You can have some Variable in Application class to save application state
say create a variable like
public static boolean isPaused;
and set it from all activity on state change
The question you're asking is applicable for iOS and Windows but not really for Android.
Android doesn't really have a concept of an application as an object, although there's an Application class. Instead, an app is a loose collection of Activities. There are many good reasons for this state of affairs; for example, it supports fast app switching and easy interaction between Activities of different apps.
The best way to coordinate your "app" so that one Activity doesn't try to do something that's already been done is to use SharedPreferences to store app state. Nearly every other way of doing it is less preferred. Even if the system kills off your entire app, SharedPreferences will maintain the current state. The Application object won't.
Also, Android is based on pausing and resuming. An Activity or activities are created, pause, and resume. They may be destroyed, but that's an extreme case. A corollary to this is that apps should not have an exit button; there's no need for one. I sometimes see apps that have one, but what they're really trying to do is shut down a background Service or process. The best way to do that is to have an affordance that says "Sleep" or similar.
Have all activities inherit from the same hierarchy and put whatever you want in OnCreate, OnPause, OnResume, OnStop, OnDestroy and call the super where applicable.
Example
Parent
IamTheParentActivity : Activity
protected void onCreate()
{
setApplicationState(ApplicationState.Running);
}
protected void onPause()
{
setApplicationState(ApplicationState.Paused);
}
private void setApplicationState(Enum ApplicationState)
{
//Some Application Level Variable
Application.State = ApplicationState
}
Children
IamTheChild : IamTheParentActivity
protected void override onCreate()
{
base.OnCreate;
do other stuff
}
I have some trouble understanding the concept of the Maps API in Android. Is it correct that every time I want to draw something new on the map, I create a new Overlay? This seems highly inefficient at a first glance. Is the whole layer structure baked down and I dont have to worry about performance at all or am I missing something like updateOverlay?
Or would I just implement my own updateOverlay() method when I extend the Overlay class and call MapView.invalidate() afterwards?
You create an overlay only once and the add it to the MapView. Then you need to call postInvalidate() on the MapView, so the new overlay will appear on the screen. Without this call, the overlay will be created, but will not show up.
Since the onResume() method in the activity lifecycle is always called when application starts or just wake up, you want to enable location tracking in onResume() and disable it in onPause(). There is a helpful method in MyLocationOverlay class: runOnFirstFix() This method allows you to set a code that will run as soon as we have location at all:
#Override
public void onResume()
{
super.onResume();
whereAmI.enableMyLocation();
whereAmI.runOnFirstFix( new Runnable() {
public void run() {
mapController.setCenter(whereAmI.getMyLocation());
}
});
}
After that, you don't need to do anything yourself, because the MyLocationOverlay is getting location updates and putting the blinking blue dot in that location.
#Override
public void onPause()
{
super.onPause();
whereAmI.disableMyLocation();
}
When I write my activities on android, I have to override a lot of "lifecycle" methods, such as onCreate, onActivityResult:
class MyAcitivity extends Activity {
#Override
public void onCreate(...) {}
#Override
public void onStart(...) {}
#Override
public void onActivityResult(...) {}
#Overide
public void onBackPressed(...) {}
}
I don't like this, because I found my logical code are split to everywhere in my class. I do some operation in this method, but I have to handle the result in another method.
Is it the only way to design Activity like this? Is there any other solution can let me do the same without overriding methods from super classes?
Update
I do some operation in this method, but I have to handle the result in another method.
For example:
public void onCreate(...) {
startActivityForResult(new Intent(this, AnotherAcitity.class), INTENT_ANOTHER);
}
public void onActivityResult(...) {
if(requestCode == INTENT_ANOTHER) {
// do something
}
}
Update again
I know how to use these lifecycle methods, what I'm thinking is the "design". Is there any different way to design android (in theory) without "overriding lifecycle methods" to write activities. Does ios and win8 on mobiles use the same design as android? If I develop an ios or win8 application, do I have to override all kinds of lifecycle methods as I do on android?
You only need to override the methods you're using in your Activity. So if your activity simple displays a help page that has already been populated in the XML, you only have to override onCreate() and call setContentView().
In general, if your overriden method is like:
public void myOverridenMethod() {
super.myOverridenMethod();
}
That is to say, it contains nothing but a super call, you need not override it.
In the example you provided, you must override the appropriate lifecycle methods as the calling of these is beyond your control, unless you're willing to develop a custom ROM for your device(s).
EDIT
The Android lifecycle methods are called by the system at specific predefined points in your app's life.
You cannot design an Activity in a different way, as if you do Android has no idea which method does what. However, it knows exactly when to call which method in the Android lifecycle. By using your own methods instead of these, you have an app which Android cannot interact with.
Additionally, many lifecycle methods like onCreate() etc. help setup the initial bits of your app (like getting it a Context).
iOS and Windows Phone and BlackBerry have similar lifecycle methods, but they don't always have an exact Android equivalent, as all are different platforms and handle their apps differently.
This is just a generic framework pattern, framework doesn't depend on you, just notifies you, all your actions are optional for framework. It's called Inversion of Control.
This is just opposite to the direct style of programming where you decide everything about the Application, and give commands to framework.
Google developers designed Activity class, and Android only works through them. Android calls these methods whenever it pleases. Android does not care what you do in those methods, it just cares to notify you of the life cycle events.
Since everything is optional, you just have to fill in the places you are really interested in. An empty Activity runs just fine.
public class MyActivity extends Activity { }
If anything additional needs to be done, just add the code at correct place:
public class MyActivity extends Activity {
#Override
public void onCreate(...) {
//---whatever you want to do in this stage of life cycle----
}
}
You dont necessarily need to override all methods of life cycle of an activty. They all are for a specified purpose
onCreate() :
Called when the activity is first created. This is where you should do
all of your normal static set up: create views, bind data to lists,
etc. This method also provides you with a Bundle containing the
activity's previously frozen state, if there was one. Always followed
by onStart().
onRestart() :
Called after your activity has been stopped, prior to it being started
again. Always followed by onStart()
onStart() :
Called when the activity is becoming visible to the user. Followed by
onResume() if the activity comes to the foreground, or onStop() if it
becomes hidden.
onResume() :
Called when the activity will start interacting with the user. At this
point your activity is at the top of the activity stack, with user
input going to it. Always followed by onPause().
onPause ():
Called as part of the activity lifecycle when an activity is going
into the background,
but has not (yet) been killed. The counterpart to onResume().
When activity B is launched in front of activity A, this callback will be invoked on A.
B will not be created until A's onPause() returns, so be sure to not
do anything lengthy here.
onStop():
Called when you are no longer visible to the user. You will next
receive either onRestart(), onDestroy(), or nothing, depending on
later user activity.
Note that this method may never be called, in low memory situations
where the system does not have enough memory to keep your activity's
process running after its onPause() method is called.
onDestroy() :
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.
I am building an android application that uses google maps to overlay items. The latitude and longitude for the items I get from a MySQL database. To do this I connect to a php script using HTTP in Async Task. My code for displaying items on the map is in the onPostExecute() method of Async Task.
Everything works fine but when I for example rotate the phone all my overlayed items disappear. How can I resolve this issue?
Should overlaying the items happen in the main thread? If so, I need to somehow pass the information from the async taks to the main thread, which I have looked into but have not been able to get that working. If somebody knows a good and right way to do this, I would really appreciate the help.
OnPostExecute it is invoked in the main thread!
Your problem is that when you rotate your phone
Android restarts the running Activity (onDestroy() is called, followed by onCreate()). The restart behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that match the new device configuration.
.http://developer.android.com/guide/topics/resources/runtime-changes.html
Async task is your thread where onpost method is default attach with main UI thread its not Async problem you just need to handle onConfigurationChanged method, better to post some code.
Use the onSaveInstanceState(Bundle outstate) and onRestoreInstanceState(Bundle savedInstanceState) of activity class.
As mentioned android restarts your activity when you change rotation. So solution to this is in onSaveInstenceState you should store you overlay items data and in onRestoreInstanceState you should recreate overlay items based on saved data
create a method named initUi() and call it in onConfigurationChanged and onCreate methods like this:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
try {
setContentView(...);
initUi();
} catch (Exception e) {
}
}
and
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_document);
initUi();
try {
} catch (Exception e) {
}
As said by the other answers you can solve your problem using onSaveInstanceState(Bundle outstate) and onRestoreInstanceState(Bundle savedInstanceState) or even disabling orientation changes in the device.
Lets see one by one:
-Disabling orientation changes, may result in a pour user experience, so I would not favour it.
-Using onSaveInstanceState(Bundle outstate) and onRestoreInstanceState(Bundle savedInstanceState) you have two main oprions ...
Option 1:
You can save only basic information about items being displayed (i.e. if it's a map, you could save map center location and zoom) and then retrieve again from the database all the overlays information. That's very simple but it may bacome very slow if you have several hundred of overlay items to retrieve, resulting again in a pour user experience.
Option 2:
You could use parcelable to extend you overlay Item so you could save all the overlay items during onSaveInstanceState(Bundle outstate), and restore them without reloading from database. I've used this for with several thousand of items, and it works quite well.
You can find parcelable information in here: Google and and example in here: Android – Parcel data to pass between Activities using Parcelable classes
Good luck