I have created an Android Application Project and in MainActivity.java > onCreate() it is calling super.onCreate(savedInstanceState).
As a beginner, can anyone explain what is the purpose of the above line?
Every Activity you make is started through a sequence of method calls. onCreate() is the first of these calls.
Each and every one of your Activities extends android.app.Activity either directly or by subclassing another subclass of Activity.
In Java, when you inherit from a class, you can override its methods to run your own code in them. A very common example of this is the overriding of the toString() method when extending java.lang.Object.
When we override a method, we have the option of completely replacing the method in our class, or of extending the existing parent class' method. By calling super.onCreate(savedInstanceState);, you tell the Dalvik VM to run your code in addition to the existing code in the onCreate() of the parent class. If you leave out this line, then only your code is run. The existing code is ignored completely.
However, you must include this super call in your method, because if you don't then the onCreate() code in Activity is never run, and your app will run into all sorts of problem like having no Context assigned to the Activity (though you'll hit a SuperNotCalledException before you have a chance to figure out that you have no context).
In short, Android's own classes can be incredibly complex. The code in the framework classes handles stuff like UI drawing, house cleaning and maintaining the Activity and application lifecycles. super calls allow developers to run this complex code behind the scenes, while still providing a good level of abstraction for our own apps.
*Derived class onCreate(bundle) method must call superclass implementation of this method. It will throw an exception SuperNotCalledException if the "super" keyword is not used.
For inheritance in Java, to override the superclass method and also to execute the above class method, use super.methodname() in the overriding derived class method;
Android class works in the same way. By extending the Activity class which have onCreate(Bundle bundle) method in which meaningful code is written and to execute that code in the defined activity, use the super keyword with the method onCreate() like super.onCreate(bundle).
This is a code written in Activity class onCreate() method and Android Dev team might add some more meaningful code to this method later. So, in order to reflect the additions, you are supposed to call the super.onCreate() in your Activity class.
protected void onCreate(Bundle savedInstanceState) {
mVisibleFromClient = mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, true);
mCalled = true;
}
boolean mVisibleFromClient = true;
/**
* Controls whether this activity main window is visible. This is intended
* only for the special case of an activity that is not going to show a
* UI itself, but can't just finish prior to onResume() because it needs
* to wait for a service binding or such. Setting this to false prevents the UI from being shown during that time.
*
* <p>The default value for this is taken from the
* {#link android.R.attr#windowNoDisplay} attribute of the activity's theme.
*/
It also maintains the variable mCalled which means you have called the super.onCreate(savedBundleInstance) in your Activity.
final void performStart() {
mCalled = false;
mInstrumentation.callActivityOnStart(this);
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStart()");
}
}
See source code here.
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/app/Activity.java#Activity.onCreate%28android.os.Bundle%29
Because upon super.onCreate() it will reach the Activity (parent class of any activity) class to load the savedInstanceState,and we normaly don't set any saved instance state, but
android framework made such a way that, we should be calling that.
It is information you want returned to your application, via onCreate(),
if the activity is destroyed and restarted due to some implicit reason
(e.g., not because the user pressed the back button). The most common
use of onSaveInstanceState() is to handle screen rotations, as by
default, activities are destroyed and recreated when the user slides out
the G1 keyboard.
The reason to call super.onCreate(savedInstanceState) is because your
code will not compile otherwise. ;-)
Related
I am asking for "Why", the reasoning behind this behavior.
The question is not a Duplicate of other "How to" type questions.
// MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fun mainFunction() {
// code
}
// AnotherClass.kt
class AnotherClass() {
fun anotherFunction() {
}
}
// SomeClass.kt
class SomeClass() {
init {
MainActivity().mainFunction() // unresolved reference ERROR
AnotherClass().anotherFunction() // Works Fine!
}
}
What is so different about Activity Class in Android? Why does Activity in Android restrict calling methods normally like other simple Classes?
Because activity it's an appcomponent managed by the OS. And methods like onCreate or onResume calling by OS. You just can decide what should be happened where this method will be called for operation system. For example:
you can release resources in the onStop or onDestroy methods.
That's because android app is working under Android OS(That have it's own rules).
For better understanding, I can recommend you to read the article:
Application Fundamentals
The Activity instance acts like a system plugin. The plugin defines various hooks for the system to call during various state of the activity. Hooks allow developer to customize the activity behavior. For example, when the system transitions an activity into the created state, it calls the onCreate hook of your plugin so that you can provide a view for the system to render inside the activity. The plugin itself does not have full control of the lifecycle of the activity, it just customizes it.
To simplify the customization, so that you can make certain assumption about the state and you can get the data you need easier, the system defines a contract. The contract defines the order of the hook invocation and the set of fields/properties which must be assigned/removed before/after calling each hook.
For the code snippet in the question, you have instantialize an activity instance, but you have not fulfilled the contract, e.g. providing an activity context, etc. If you try to call the methods inherited from the Activity class, it is likely to crash since the assumptions made by the implementation is no longer valid and it is trying to access some fields/properties which have not been properly initialized.
I need to show some dialogs as debug in my app.
The structure of the app itself is written so that it is easier to actually call and show the dialog from a static class with static methods. These methods all points toward a bigger method which eventually take care of the requests.
What I'd like to achieve is to call an eventual Dialog (I'm using the Material Dialog library by afollestad on github) which needs a reference to the current activity.
I actually have a private static Activity sActivity; field in the class, and the relative setActivity(Activity activity) method.
Currently, I've got my own CustomApplication from which I call this:
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
MyStaticClass.setActivity(activity);
}
[...]
}
which is not working as intended because this
try {
Utils.showSimpleDialog(sActivity, "Error", message);
} catch (MaterialDialog.DialogException d) {
d.printStackTrace();
}
is always calling the catch case.
My question is, is it possible to avoid the setActivity call from every single Activity? If yes, how? Thank in advance!
It's not a good idea to keep a static reference to an Activity as it can cause memory leaks with leaked contexts.
Edit to answer if it would still be dangerous if setting static activity to null in onDestroy as previously asked in a comment under this answer
Setting to null in onDestroy doesn't always serve as a workaround to this because if you run out of memory you can get into a state where Android can actually stop at the onPause stage of the lifecycle and not even hit onDestroy. Keeping static contexts is generally to be avoided.
It looks like showSimpleDialog already takes an Activity parameter. When you are calling it from an Activity, simply pass this , or from a fragment, pass getActivity(). If this call to showSimpleDialog is called from another utility method you've implemented, just pass an activity to that method also rather than setting a static Activity on the class.
I'm extending the Application class for my additional custom need. And I'm calling a method inside that. As the expected behaviour, it is getting invoked for type of Android components(Activity, Service, Broadcast receiver, etc.,) But I want that too be invoked only on Activity. Is that any other way to overcome this problem ?
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// the below method needs to invoked only for service
// but now called for all application components
myCustomMethod();
}
....
}
But I want that too be invoked only on Activity.
Can't be done. The Application instance will run if one component of your Application is open.
You need to do the customized stuff in another class and open it just when the instance of your desire component is open.
just add your code to onCreate method of your entry-point activity. If you want it to be called once per session - add two int keys to your shared preferences - app_launch_count and method_invoke_count. Increment first on App's onCreate and check the second in your Activity's onCreate if first greater then invoke the method :)
Move myCustomMethod() into the activity. An Application has no way of knowing what triggered the creation of its process.
Or, use registerActivityLifecycleCallbacks() on Application to register an ActivityLifecycleCallbacks object, and put your myCustomMethod() logic in onActivityCreated(). This requires a minSdkVersion of 14 or higher. That will tell you when each activity is created after your process is instantiated — if you only care about the first one, you would have to unregister the callbacks in your onActivityCreated() implementation.
I am trying to use this solution inside my Fragment, however I couldn't be sure where to call System.LoadLibrary(), finally I decided to call from onCreate method of the Fragment, I want to be sure if this would not raise some another weird error on different devices.
General it won't cause weird behaviours, as onCreate is mandatory callback when your fragment created by system. This make sure your native library is prepared before you do further operation in your fragment.
Take a look at fragment life cycle, it might be better if you put your library initialize routine on the first callback onAttach, you can use the attached Activity context to initialize your native library.
It is just a static initialization. You don't even have to have it inside your onCreate() at all. You can simply initialize it as the first part of your class next to your global variables as such:
class YourClass
{
static
{
System.loadLibrary( yourLib );
}
...
}
It is only important that it is done early or you may see UnsatisfiedLinkError followed by application's crash. That way whenever a call referenced later is made, the library itself has already been loaded. A static declaration at the top will do that as soon as an instance of the class has been requested; even before onCreate().
I have started to explore the android world just some days ago, and I am doing it via the book by Mario Zechner, "Beginning Android Games".
I might have a ton of questions about the platform and the few things I have seen so far but I know it's going to get better. All I want to ask at the moment is about activities: I saw the activity life cycle. I know that activities are something like screens. The thing I don't know is that whether I have to specify the onCreate(), onResume() etc. methods in every activity I code.
As far as I know onCreate() is compulsory and the other methods depends on how you use the activity
The entire lifetime of an activity happens between the first call to onCreate(Bundle) through to a single final call to onDestroy(). An activity will do all setup of "global" state in onCreate(), and release all remaining resources in onDestroy(). So onCreate(Bundle) should have be there in activity.
Use of onResume() depends upon your application requirement.
for more details go to http://developer.android.com/reference/android/app/Activity.html
Welcome to the world of Android.
In general, it is good practice to flesh out all the methods such as onPause(), onResume() but when you create an android program, generally you only need to flesh out the onCreate() method for activities.
Besides the onCreate, and pardon if my terminology is incorrect, the other methods follow a "default" behavior if you do not override them. So if you need the application to do something specific when it is paused, that would be a good time to add your version of onPause(), otherwise you can leave it left out.
It is not mandatory that you have to specify all those methods or any of them. It depends on what type of implementation you want
Example
I have created my Activity (A) as it extends Activity I donot override any of methods like onCreate() but I have created some variables and created some of methods.
Let us assume I created second activity there I want to shoe some view I have used onCreate() method also If I want variables and methods which I have defined in activity A I can get those variables and methods If I write class B extends A
So it is not mandatory to use all those methods from activity. If you donot write your own implementation then the default implementation will come to play.
Short answer will be NO
You don't need to specify in code of each Activity onCreate and so on. Anyway in parent Activity there will be onCreate
But long answer says: good practice is not rely on implicit/invisible code, but to have code under your control (even if it's dummy). I used to code all onCreate/onDestroy, etc in this way:
public static final boolean DEBUG=true;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if(DEBUG)
Log.d(TAG, "Creating "+this.toString());
}
You should write onCreate() method by overriding it from the base class Activity to set the view. View should be generated here itself using setContentView() method in onCreate() method.
Regarding onResume(), onPause() and other methods, it is not mandatory to write these but are useful when you need to achieve specific functionality.
Also, being a beginner please have a look at the table 1 in this document: http://developer.android.com/guide/topics/fundamentals/activities.html