How to redefine Android Application Class Android 14.04.2017

The Application class in Android is the base class within an Android app that contains all other components such as activities and services. The Application class, or any subclass of the Application class, is instantiated before any other class when the process for your application/package is created.

android_app.png

If you do not specify Application in your AndroidManifest.xml file, the Android system creates a default object for you. It is started in a new process with a unique ID under a unique user. This object provides the following main life-cycle methods:

  • onCreate() - called before the first components of the application starts.
  • onLowMemory() - called when the Android system requests that the application cleans up memory.
  • onTrimMemory() - called when the Android system requests that the application cleans up memory. This message includes an indicator in which position the application is. For example the constant TRIM_MEMORY_MODERATE indicates that the process is around the middle of the background LRU list; freeing memory can help the system keep other processes running later in the list for better overall performance.
  • onTerminate() - only for testing, not called in production.
  • onConfigurationChanged() - called whenever the configuration changes.

The application object starts before any component and runs at least as long as another component of the application runs.

Application class is primarily used for initialization of global state before the first Activity is displayed.

In many apps, there's no need to work with an application class directly. However, there are a few acceptable uses of a custom application class:

  • Specialized tasks that need to run before the creation of your first activity.
  • Global initialization that needs to be shared across all components (crash reporting, persistence).
  • Static methods for easy access to static immutable data such as a shared network client object.

Note that you should never store mutable shared data inside the Application object since that data might disappear or become invalid at any time. The application object is not guaranteed to stay in memory forever, it will get killed. Instead, store any mutable shared data using persistence strategies such as files, SharedPreferences or SQLite.

If we do want a custom application class, we start by creating a new class which extends android.app.Application as follows:

import android.app.Application;

public class MyApplication extends Application {
    // Called when the application is starting, before any other application objects have been created.
    // Overriding this method is totally optional!
    @Override
    public void onCreate() {
        super.onCreate();
        // Required initialization logic here!
    }

    // Called by the system when the device configuration changes while your component is running.
    // Overriding this method is totally optional!
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    // This is called when the overall system is running low on memory, 
    // and would like actively running processes to tighten their belts.
    // Overriding this method is totally optional!
    @Override
    public void onLowMemory() {
        super.onLowMemory();
    }
}

And specify the android:name property in the the <application> node in AndroidManifest.xml:

<application 
   android:name=".MyApplication"
   android:icon="@drawable/icon" 
   android:label="@string/app_name" 
   ...>

That's all you should need to get started with your custom application.

Following is examples of Application redefining.

You may need to know if the app runs for the first time. Suppose, you get to show the user the EULA (End User License Agreement) page for the first time. In this case you can save the value in preferences and when the app get started you can call isFirstRun() to know if it is first time, after that call setRunned() method, which will set the value false.

public class MyApplication extends Application {
    SharedPreferences sp;

    @Override
    public void onCreate() {
        super.onCreate();
        sp = getApplicationContext().getSharedPreferences("PREF_KEY", MODE_PRIVATE);
    }

    public boolean isFirstRun() {
        return sp.getBoolean("is_first_run", true);
    }

    public void setRunned() {
        // after a successful run, call this method to set first run false 
        SharedPreferences.Editor edit = sp.edit();
        edit.putBoolean("is_first_run", false);
        edit.commit();
    }    
}

Sometimes you want to store data, like global variables which need to be accessed from multiple Activities – sometimes everywhere within the application. In this case, the Application object will help you.

For example, if you want to get the basic authentication data for each http request, you can implement the methods for authentication data in the application object.

public class MyApplication extends Application {
    private String username;
    private String password;

    @Override
    public void onCreate() {
        // Here you could pull values from a config file in res/raw or somewhere else
        // but for simplicity's sake, we'll just hardcode values
        username = "proft";
        password = "******";
        super.onCreate();
    }

    public String getUsername() {
        return username;
    }

    public void getPassword() {
        return password;
    }
}

After this,you can get the username and password in any of the activities like this:

MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();

How to exit Application

Unfortunately, Android Design does not provide any exit choice but we can exit the application via Intent.

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

How to detect when an Android app goes to the background and come back to the foreground

We don’t have any direct approach to find whether our application gone to background but we have few interfaces from android which helps to solve this.

The following interfaces which help us are:

  • Application.ActivityLifecycleCallbacks. This interface helps us to trigger the life cycle of all activities. We can use this ActivityLifecycleCallbacks interface in the Custom Application class. So that we can trigger all the activity life cycles at one location.
  • ComponentCallbacks2. This class extended ComponentCallbacks interface with a new callback for finer-grained memory management. This interface is available in all application components (Activity, Service, ContentProvider, and Application).

Both the interfaces are added in API level 14.

So, using your Application object, you can register a listener for activity lifecycle changes, and keep track of your application's state.

For this purpose you must use ActivityLifecycleCallbacks. ActivityLifecycleCallbacks is interface of Application.class. Can handle the called lifeCycle of Activity.

public class MyApplication extends Application {
    @Override
    public void onCreate (){
        super.onCreate();
        registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks());
    }

    @Override
    public void onTerminate (){
        super.onTerminate();
    }

    @Override
    public void onConfigurationChanged (Configuration newConfig){
        super.onConfigurationChanged(newConfig);
    }

    private static final class MyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {
        public void onActivityCreated(Activity activity, Bundle bundle) {
            Log.d("TAG", "onActivityCreated:" + activity.getLocalClassName());
        }

        public void onActivityDestroyed(Activity activity) {
            Log.d("TAG", "onActivityDestroyed:" + activity.getLocalClassName());
        }

        public void onActivityPaused(Activity activity) {
            Log.d("TAG", "onActivityPaused:" + activity.getLocalClassName());
        }

        public void onActivityResumed(Activity activity) {
            Log.d("TAG", "onActivityResumed:" + activity.getLocalClassName());
        }

        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            Log.d("TAG", "onActivitySaveInstanceState:" + activity.getLocalClassName());
        }

        public void onActivityStarted(Activity activity) {
            Log.d("TAG", "onActivityStarted:" + activity.getLocalClassName());
        }

        public void onActivityStopped(Activity activity) {
            Log.d("TAG", "onActivityStopped:" + activity.getLocalClassName());
        }
    }
}