restart app when global static variables are killed android - android

I have many global final constants in my application. I populate these constants from a json file during application startup. As recommended by many people, I am using the application class to keep the global variables in memory. But sometimes, after I close the application and play around with other apps and then come back to my app, it crashes. I understand this is because the system kills the process so these static variables are lost from memory. The recommended solution is to use sharedpreferences or other persistant storage methods to store these global variables. But I need a quick and easy solution to 'fix' this issue. For example, What is the easiest way to force restart the app, if the system kills the process(while the app in running in the background) and user comes back to the app later? I hope my question is clear.
Thanks in advance
Tom

As Kai suggested, i.e.:
public class MyApplication extends Application {
#Override
public void onCreate(){
super.onCreate();
initVariables();
}
}
Or use accessors:
public class MyApplication extends Application {
MyVar var;
public MyVar getVar(){
if(var == null){
initVariables();
}
return var;
}
}

Once your app is being paused (not visible to users), by specification Android system can simply kill the process your app resides in without any additional callback, so what you are trying to do is playing against system behavior.
If you keep those variables in your Application class, then you can simply reload those variables when your Application class is being loaded.

Related

Can I call static method from Activity if Activity is destroyed?

In Xamarin.Android if an Activity gets killed because of low memory can I still call static methods defined in that Activity from another Activity. For example:
public class MyKilledActivity : Activity
{
....
public static int MyStaticMethod()
{
.....
return someIntValue;
}
}
public class AnotherActivity : Activity
{
.....
int value = MyKilledActivity.MyStaticMethod(); // Would it work if MyKilledActivity is destroyed?
}
You can always call a static method on any accessible class at any time. Just use MyClass.staticMethod(). Note that you can't call deadInstanceOfMyClass.staticMethod() this way if deadInstanceOfMyClass == null.
Can I call static method from Activity if Activity is destroyed?
Just as SushiHangover said, the answer is Yes.
In Xamarin.Android if an Activity gets killed because of low memory can I still call static methods defined in that Activity from another Activity?
Please note that Android doesn't kill single activities, Android kills processes.
Processes are roughly an app and everything in that app- all the activities, services, application class related to that particular app, in most cases one app equals one process.
That means, that if Android trimmed a process, all the activities (and everything else related to that app) inside it will also die as a result. Android (and in particular, the Android Kernel which is responsible for killing processes when reaching certain memory thresholds) doesn't trim single components within that process/ within that app, it doesn't even know or care that they exist.
So if your app is killed via system because of low memory, then, all your Activity will be destroyed.
Yes, assuming someIntValue is either static or a hardcoded Integer value.

Is there any drawback to implementing member variable free activities?

I started to learn the android framework and my biggest problem is the hell around the activity life cycle. So when the user rotate the screen my application just crash. As I understand beside the normal activity life cycle Android hacked a force-instance-deleter-and-partially-recovery service for me which is not a bug but a feature.
So I just want my member variable keeps safe, so a I thought a start storing it in the Application class.
So I want to refactor my program in the following way:
I create an own Application
public class MainApp extends Application {
LoginActivityData loginActivityData; // create data "segment" for every activity
FirstActivityData firstActivityData;
...
public static MainApp getInstance(final Context context) {
if (context == null) return null;
final Context app = context.getApplicationContext();
return app instanceof MainApp ? (MainApp) app : null;
}
}
In activities and fragments I stop using member variables except the one from the MainApp class.
public class LoginActivity extends Activity {
LoginActivityData loginActivityData;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loginActivityData = MainApp.getInstance(this).loginActivityData;
}
Is there any drawback of this design?
Yes, there is a drawback. Your application object can and will be destroyed by the system when it needs to recover memory, and the application object does not have callback methods that can be used to save state. See here for a fuller explanation.
There are many ways to persist data/state, but if you use the following approach you generally won't go far wrong:
Use onPause() to save long-term data to a SQLite DB/SharedPreferences/cloud etc. Restore it wherever appropriate (onCreate(), onResume(), ...).
Use onSaveInstanceState() to save temporary data to a Bundle. Restore it in onCreate()/onRestoreInstanceState(). The bundle is automatically passed around to the appropriate methods by the system. Note that there is no guarantee that onSaveInstanceState() will be called, so don't use it for critical data.

Why extend the Android Application class?

An extended Application class can declare global variables. Are there other reasons?
Introduction:
If we consider an apk file in our mobile, it is comprised of
multiple useful blocks such as, Activitys, Services and
others.
These components do not communicate with each other regularly and
not forget they have their own life cycle. which indicate that
they may be active at one time and inactive the other moment.
Requirements:
Sometimes we may require a scenario where we need to access a
variable and its states across the entire Application regardless of
the Activity the user is using,
An example is that a user might need to access a variable that holds his
personnel information (e.g. name) that has to be accessed across the
Application,
We can use SQLite but creating a Cursor and closing it again and
again is not good on performance,
We could use Intents to pass the data but it's clumsy and activity
itself may not exist at a certain scenario depending on the memory-availability.
Uses of Application Class:
Access to variables across the Application,
You can use the Application to start certain things like analytics
etc. since the application class is started before Activitys or
Servicess are being run,
There is an overridden method called onConfigurationChanged() that is
triggered when the application configuration is changed (horizontal
to vertical & vice-versa),
There is also an event called onLowMemory() that is triggered when
the Android device is low on memory.
Application class is the object that has the full lifecycle of your application. It is your highest layer as an application. example possible usages:
You can add what you need when the application is started by overriding onCreate in the Application class.
store global variables that jump from Activity to Activity. Like Asynctask.
etc
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.
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();
And finally, do remember to use the Application object as a singleton object:
public class MyApplication extends Application {
private static MyApplication singleton;
public MyApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
For more information, please Click Application Class
Offhand, I can't think of a real scenario in which extending Application is either preferable to another approach or necessary to accomplish something. If you have an expensive, frequently used object you can initialize it in an IntentService when you detect that the object isn't currently present. Application itself runs on the UI thread, while IntentService runs on its own thread.
I prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences. There are also ways to pass data from a Fragment to its parent Activity using interfaces.
The Application class is a singleton that you can access from any activity or anywhere else you have a Context object.
You also get a little bit of lifecycle.
You could use the Application's onCreate method to instantiate expensive, but frequently used objects like an analytics helper. Then you can access and use those objects everywhere.
Best use of application class.
Example: Suppose you need to restart your alarm manager on boot completed.
public class BaseJuiceApplication extends Application implements BootListener {
public static BaseJuiceApplication instance = null;
public static Context getInstance() {
if (null == instance) {
instance = new BaseJuiceApplication();
}
return instance;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onBootCompleted(Context context, Intent intent) {
new PushService().scheduleService(getInstance());
//startToNotify(context);
}
Not an answer but an observation: keep in mind that the data in the extended application object should not be tied to an instance of an activity, as it is possible that you have two instances of the same activity running at the same time (one in the foreground and one not being visible).
For example, you start your activity normally through the launcher, then "minimize" it. You then start another app (ie Tasker) which starts another instance of your activitiy, for example in order to create a shortcut, because your app supports android.intent.action.CREATE_SHORTCUT. If the shortcut is then created and this shortcut-creating invocation of the activity modified the data the application object, then the activity running in the background will start to use this modified application object once it is brought back to the foreground.
I see that this question is missing an answer. I extend Application because I use Bill Pugh Singleton implementation (see reference) and some of my singletons need context. The Application class looks like this:
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private static MyApplication sInstance;
#Contract(pure = true)
#Nullable
public static Context getAppContext() {
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() called");
sInstance = this;
}
}
And the singletons look like this:
public class DataManager {
private static final String TAG = DataManager.class.getSimpleName();
#Contract(pure = true)
public static DataManager getInstance() {
return InstanceHolder.INSTANCE;
}
private DataManager() {
doStuffRequiringContext(MyApplication.getAppContext());
}
private static final class InstanceHolder {
#SuppressLint("StaticFieldLeak")
private static final DataManager INSTANCE = new DataManager();
}
}
This way I don't need to have a context every time I'm using a singleton and get lazy synchronized initialization with minimal amount of code.
Tip: updating Android Studio singleton template saves a lot of time.
I think you can use the Application class for many things, but they are all tied to your need to do some stuff BEFORE any of your Activities or Services are started.
For instance, in my application I use custom fonts. Instead of calling
Typeface.createFromAsset()
from every Activity to get references for my fonts from the Assets folder (this is bad because it will result in memory leak as you are keeping a reference to assets every time you call that method), I do this from the onCreate() method in my Application class:
private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
super.onCreate();
appInstance = this;
quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
"fonts/Quicksand-Regular.otf");
...
}
Now, I also have a method defined like this:
public static App getAppInstance() {
return appInstance;
}
and this:
public Typeface getQuickSandRegular() {
return quicksandRegular;
}
So, from anywhere in my application, all I have to do is:
App.getAppInstance().getQuickSandRegular()
Another use for the Application class for me is to check if the device is connected to the Internet BEFORE activities and services that require a connection actually start and take necessary action.
Source: https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class
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
You should never store mutable instance data inside the Application object because if you assume that your data will stay there, your application will inevitably crash at some point with a NullPointerException. The application object is not guaranteed to stay in memory forever, it will get killed. Contrary to popular belief, the app won’t be restarted from scratch. Android will create a new Application object and start the activity where the user was before to give the illusion that the application was never killed in the first place.
To add onto the other answers that state that you might wish store variables in the application scope, for any long-running threads or other objects that need binding to your application where you are NOT using an activity (application is not an activity).. such as not being able to request a binded service.. then binding to the application instance is preferred. The only obvious warning with this approach is that the objects live for as long as the application is alive, so more implicit control over memory is required else you'll encounter memory-related problems like leaks.
Something else you may find useful is that in the order of operations, the application starts first before any activities. In this timeframe, you can prepare any necessary housekeeping that would occur before your first activity if you so desired.
2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
You can access variables to any class without creating objects, if its extended by Application. They can be called globally and their state is maintained till application is not killed.
The use of extending application just make your application sure for any kind of operation that you want throughout your application running period. Now it may be any kind of variables and suppose if you want to fetch some data from server then you can put your asynctask in application so it will fetch each time and continuously, so that you will get a updated data automatically.. Use this link for more knowledge....
http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android

Android Application life cycle and singelton

well most of us familiar with this pattern:
public class MySingeltone {
public String mSomeReferenceTypeData;
public int mSomeValueTypeData;
private static MySingeltone mInstance;
private MySingeltone() {
}
public static MySingeltone getInstance() {
if (mInstance == null) {
mInstance = new MySingeltone();
}
return mInstance;
}
}
my problem is that I've found recently that the mInstance don't equal null after activity using him been destroyed, or when the whole application suppose to be clause, for example:
public class SomeActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MySingeltone mySingeltone = MySingeltone.getInstance();
mySingeltone.mSomeReferenceTypeData = "some value";
}
}
when launching "SomeActivity" next time after closing the whole applications running activities (say 10 seconds after..) the mInstance still holds the same reference, with the same values on his fields.
why does it happening?
what am I missing?
when android garbage collecting static members belongs to application?
Since "mInstance" is a static variable it will not get null when you close your application. Closing of application doesn't means that your application got destroyed.
Also there is no concept of Closing your Android app. If you get out of your app it will not get destroyed at the same time. Android OS handles it internally when to close the app when it is no more in use. In case of memory shortage when android decides to destroy the app then this static variable will also got null.
You can not control when exactly Java objects become garbage collected. An object becomes eligible for garbage collection when there are no more (non-circular) references to it.
With Android, further, you can not control when your Activity gets removed from memory.
why does it happening?
what am I missing?
when android garbage collecting static members belongs to application?
Ok first, as others said, there is no close application concept on Android as the android OS manages lifecycle of your application process on their own.
Second, you did the wrong test - if instead of closing all apps you would do the opposite - that is - fill up memory by starting more and more apps, then eventually your application's memory would be cleaned up to be used by other applications and this includes all static mebers as well as instance members! then, you will see that the static variable WILL BE NULL as you expected.
They just "lazily" clean up memory, if there's enough memory then you application might never get cleaned up.
Actually, there is no way around it, as far as i know, there is no way to grauntee an object would not be cleaned up at any point from the device memory. in somecases it leads to bad behaviour. such as if the singleton does heavy processing on its creation, calling getInstance might get your UI stuck, or even make your app crash due to irresponsibleness.

How to declare global variables in Android?

I am creating an application which requires login. I created the main and the login activity.
In the main activity onCreate method I added the following condition:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
...
loadSettings();
if(strSessionString == null)
{
login();
}
...
}
The onActivityResult method which is executed when the login form terminates looks like this:
#Override
public void onActivityResult(int requestCode,
int resultCode,
Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode)
{
case(SHOW_SUBACTICITY_LOGIN):
{
if(resultCode == Activity.RESULT_OK)
{
strSessionString = data.getStringExtra(Login.SESSIONSTRING);
connectionAvailable = true;
strUsername = data.getStringExtra(Login.USERNAME);
}
}
}
The problem is the login form sometimes appears twice (the login() method is called twice) and also when the phone keyboard slides the login form appears again and I guess the problem is the variable strSessionString.
Does anyone know how to set the variable global in order to avoid login form appearing after the user already successfully authenticates?
I wrote this answer back in '09 when Android was relatively new, and there were many not well established areas in Android development. I have added a long addendum at the bottom of this post, addressing some criticism, and detailing a philosophical disagreement I have with the use of Singletons rather than subclassing Application. Read it at your own risk.
ORIGINAL ANSWER:
The more general problem you are encountering is how to save state across several Activities and all parts of your application. A static variable (for instance, a singleton) is a common Java way of achieving this. I have found however, that a more elegant way in Android is to associate your state with the Application context.
As you know, each Activity is also a Context, which is information about its execution environment in the broadest sense. Your application also has a context, and Android guarantees that it will exist as a single instance across your application.
The way to do this is to create your own subclass of android.app.Application, and then specify that class in the application tag in your manifest. Now Android will automatically create an instance of that class and make it available for your entire application. You can access it from any context using the Context.getApplicationContext() method (Activity also provides a method getApplication() which has the exact same effect). Following is an extremely simplified example, with caveats to follow:
class MyApp extends Application {
private String myState;
public String getState(){
return myState;
}
public void setState(String s){
myState = s;
}
}
class Blah extends Activity {
#Override
public void onCreate(Bundle b){
...
MyApp appState = ((MyApp)getApplicationContext());
String state = appState.getState();
...
}
}
This has essentially the same effect as using a static variable or singleton, but integrates quite well into the existing Android framework. Note that this will not work across processes (should your app be one of the rare ones that has multiple processes).
Something to note from the example above; suppose we had instead done something like:
class MyApp extends Application {
private String myState = /* complicated and slow initialization */;
public String getState(){
return myState;
}
}
Now this slow initialization (such as hitting disk, hitting network, anything blocking, etc) will be performed every time Application is instantiated! You may think, well, this is only once for the process and I'll have to pay the cost anyways, right? For instance, as Dianne Hackborn mentions below, it is entirely possible for your process to be instantiated -just- to handle a background broadcast event. If your broadcast processing has no need for this state you have potentially just done a whole series of complicated and slow operations for nothing. Lazy instantiation is the name of the game here. The following is a slightly more complicated way of using Application which makes more sense for anything but the simplest of uses:
class MyApp extends Application {
private MyStateManager myStateManager = new MyStateManager();
public MyStateManager getStateManager(){
return myStateManager ;
}
}
class MyStateManager {
MyStateManager() {
/* this should be fast */
}
String getState() {
/* if necessary, perform blocking calls here */
/* make sure to deal with any multithreading/synchronicity issues */
...
return state;
}
}
class Blah extends Activity {
#Override
public void onCreate(Bundle b){
...
MyStateManager stateManager = ((MyApp)getApplicationContext()).getStateManager();
String state = stateManager.getState();
...
}
}
While I prefer Application subclassing to using singletons here as the more elegant solution, I would rather developers use singletons if really necessary over not thinking at all through the performance and multithreading implications of associating state with the Application subclass.
NOTE 1: Also as anticafe commented, in order to correctly tie your Application override to your application a tag is necessary in the manifest file. Again, see the Android docs for more info. An example:
<application
android:name="my.application.MyApp"
android:icon="..."
android:label="...">
</application>
NOTE 2: user608578 asks below how this works with managing native object lifecycles. I am not up to speed on using native code with Android in the slightest, and I am not qualified to answer how that would interact with my solution. If someone does have an answer to this, I am willing to credit them and put the information in this post for maximum visibility.
ADDENDUM:
As some people have noted, this is not a solution for persistent state, something I perhaps should have emphasized more in the original answer. I.e. this is not meant to be a solution for saving user or other information that is meant to be persisted across application lifetimes. Thus, I consider most criticism below related to Applications being killed at any time, etc..., moot, as anything that ever needed to be persisted to disk should not be stored through an Application subclass. It is meant to be a solution for storing temporary, easily re-creatable application state (whether a user is logged in for example) and components which are single instance (application network manager for example) (NOT singleton!) in nature.
Dayerman has been kind enough to point out an interesting conversation with Reto Meier and Dianne Hackborn in which use of Application subclasses is discouraged in favor of Singleton patterns. Somatik also pointed out something of this nature earlier, although I didn't see it at the time. Because of Reto and Dianne's roles in maintaining the Android platform, I cannot in good faith recommend ignoring their advice. What they say, goes. I do wish to disagree with the opinions, expressed with regards to preferring Singleton over Application subclasses. In my disagreement I will be making use of concepts best explained in this StackExchange explanation of the Singleton design pattern, so that I do not have to define terms in this answer. I highly encourage skimming the link before continuing. Point by point:
Dianne states, "There is no reason to subclass from Application. It is no different than making a singleton..." This first claim is incorrect. There are two main reasons for this. 1) The Application class provides a better lifetime guarantee for an application developer; it is guaranteed to have the lifetime of the application. A singleton is not EXPLICITLY tied to the lifetime of the application (although it is effectively). This may be a non-issue for your average application developer, but I would argue this is exactly the type of contract the Android API should be offering, and it provides much more flexibility to the Android system as well, by minimizing the lifetime of associated data. 2) The Application class provides the application developer with a single instance holder for state, which is very different from a Singleton holder of state. For a list of the differences, see the Singleton explanation link above.
Dianne continues, "...just likely to be something you regret in the future as you find your Application object becoming this big tangled mess of what should be independent application logic." This is certainly not incorrect, but this is not a reason for choosing Singleton over Application subclass. None of Diane's arguments provide a reason that using a Singleton is better than an Application subclass, all she attempts to establish is that using a Singleton is no worse than an Application subclass, which I believe is false.
She continues, "And this leads more naturally to how you should be managing these things -- initializing them on demand." This ignores the fact that there is no reason you cannot initialize on demand using an Application subclass as well. Again there is no difference.
Dianne ends with "The framework itself has tons and tons of singletons for all the little shared data it maintains for the app, such as caches of loaded resources, pools of objects, etc. It works great." I am not arguing that using Singletons cannot work fine or are not a legitimate alternative. I am arguing that Singletons do not provide as strong a contract with the Android system as using an Application subclass, and further that using Singletons generally points to inflexible design, which is not easily modified, and leads to many problems down the road. IMHO, the strong contract the Android API offers to developer applications is one of the most appealing and pleasing aspects of programming with Android, and helped lead to early developer adoption which drove the Android platform to the success it has today. Suggesting using Singletons is implicitly moving away from a strong API contract, and in my opinion, weakens the Android framework.
Dianne has commented below as well, mentioning an additional downside to using Application subclasses, they may encourage or make it easier to write less performance code. This is very true, and I have edited this answer to emphasize the importance of considering perf here, and taking the correct approach if you're using Application subclassing. As Dianne states, it is important to remember that your Application class will be instantiated every time your process is loaded (could be multiple times at once if your application runs in multiple processes!) even if the process is only being loaded for a background broadcast event. It is therefore important to use the Application class more as a repository for pointers to shared components of your application rather than as a place to do any processing!
I leave you with the following list of downsides to Singletons, as stolen from the earlier StackExchange link:
Inability to use abstract or interface classes;
Inability to subclass;
High coupling across the application (difficult to modify);
Difficult to test (can't fake/mock in unit tests);
Difficult to parallelize in the case of mutable state (requires extensive locking);
and add my own:
Unclear and unmanageable lifetime contract unsuited for Android (or most other) development;
Create this subclass
public class MyApp extends Application {
String foo;
}
In the AndroidManifest.xml add android:name
Example
<application android:name=".MyApp"
android:icon="#drawable/icon"
android:label="#string/app_name">
The suggested by Soonil way of keeping a state for the application is good, however it has one weak point - there are cases when OS kills the entire application process. Here is the documentation on this - Processes and lifecycles.
Consider a case - your app goes into the background because somebody is calling you (Phone app is in the foreground now). In this case && under some other conditions (check the above link for what they could be) the OS may kill your application process, including the Application subclass instance. As a result the state is lost. When you later return to the application, then the OS will restore its activity stack and Application subclass instance, however the myState field will be null.
AFAIK, the only way to guarantee state safety is to use any sort of persisting the state, e.g. using a private for the application file or SharedPrefernces (it eventually uses a private for the application file in the internal filesystem).
Just a note ..
add:
android:name=".Globals"
or whatever you named your subclass to the existing <application> tag. I kept trying to add another <application> tag to the manifest and would get an exception.
What about ensuring the collection of native memory with such global structures?
Activities have an onPause/onDestroy() method that's called upon destruction, but the Application class has no equivalents. What mechanism are recommended to ensure that global structures (especially those containing references to native memory) are garbage collected appropriately when the application is either killed or the task stack is put in the background?
I couldn't find how to specify the application tag either, but after a lot of Googling, it became obvious from the manifest file docs: use android:name, in addition to the default icon and label in the application stanza.
android:name
The fully qualified name of an Application subclass implemented for the application. When the application process is started, this class is instantiated before any of the application's components.
The subclass is optional; most applications won't need one. In the absence of a subclass, Android uses an instance of the base Application class.
Just you need to define an application name like below which will work:
<application
android:name="ApplicationName" android:icon="#drawable/icon">
</application>
Like there was discussed above OS could kill the APPLICATION without any notification (there is no onDestroy event) so there is no way to save these global variables.
SharedPreferences could be a solution EXCEPT you have COMPLEX STRUCTURED variables (in my case I had integer array to store the IDs that the user has already handled). The problem with the SharedPreferences is that it is hard to store and retrieve these structures each time the values needed.
In my case I had a background SERVICE so I could move this variables to there and because the service has onDestroy event, I could save those values easily.
If some variables are stored in sqlite and you must use them in most activities in your app.
then Application maybe the best way to achieve it.
Query the variables from database when application started and store them in a field.
Then you can use these variables in your activities.
So find the right way, and there is no best way.
You can have a static field to store this kind of state. Or put it to the resource Bundle and restore from there on onCreate(Bundle savedInstanceState). Just make sure you entirely understand Android app managed lifecycle (e.g. why login() gets called on keyboard orientation change).
DO N'T Use another <application> tag in manifest file.Just do one change in existing <application> tag , add this line android:name=".ApplicationName" where, ApplicationName will be name of your subclass(use to store global) that, you is about to create.
so, finally your ONE AND ONLY <application> tag in manifest file should look like this :-
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.NoActionBar"
android:name=".ApplicationName"
>
you can use Intents , Sqlite , or Shared Preferences . When it comes to the media storage, like documents , photos , and videos, you may create the new files instead.
You can do this using two approaches:
Using Application class
Using Shared Preferences
Using Application class
Example:
class SessionManager extends Application{
String sessionKey;
setSessionKey(String key){
this.sessionKey=key;
}
String getSessisonKey(){
return this.sessionKey;
}
}
You can use above class to implement login in your MainActivity as below. Code will look something like this:
#override
public void onCreate (Bundle savedInstanceState){
// you will this key when first time login is successful.
SessionManager session= (SessionManager)getApplicationContext();
String key=getSessisonKey.getKey();
//Use this key to identify whether session is alive or not.
}
This method will work for temporary storage. You really do not any idea when operating system is gonna kill the application, because of low memory.
When your application is in background and user is navigating through other application which demands more memory to run, then your application will be killed since operating system given more priority to foreground processes than background.
Hence your application object will be null before user logs out. Hence for this I recommend to use second method Specified above.
Using shared preferences.
String MYPREF="com.your.application.session"
SharedPreferences pref= context.getSharedPreferences(MyPREF,MODE_PRIVATE);
//Insert key as below:
Editot editor= pref.edit();
editor.putString("key","value");
editor.commit();
//Get key as below.
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
String key= getResources().getString("key");
On activity result is called before on resume. So move you login check to on resume and your second login can be blocked once the secomd activity has returned a positive result. On resume is called every time so there is not worries of it not being called the first time.
The approach of subclassing has also been used by the BARACUS framework. From my point of view subclassing Application was intended to work with the lifecycles of Android; this is what any Application Container does. Instead of having globals then, I register beans to this context an let them beeing injected into any class manageable by the context. Every injected bean instance actually is a singleton.
See this example for details
Why do manual work if you can have so much more?
class GlobaleVariableDemo extends Application {
private String myGlobalState;
public String getGlobalState(){
return myGlobalState;
}
public void setGlobalState(String s){
myGlobalState = s;
}
}
class Demo extends Activity {
#Override
public void onCreate(Bundle b){
...
GlobaleVariableDemo appState = ((GlobaleVariableDemo)getApplicationContext());
String state = appState.getGlobalState();
...
}
}
You could create a class that extends Application class and then declare your variable as a field of that class and providing getter method for it.
public class MyApplication extends Application {
private String str = "My String";
synchronized public String getMyString {
return str;
}
}
And then to access that variable in your Activity, use this:
MyApplication application = (MyApplication) getApplication();
String myVar = application.getMyString();

Categories

Resources