Application arraylist clears - android

I have an application which has several screens. Lets say A B C D and D might open some external application as well.
All this activities share data, an arraylist with one another and I have created a reference to it in my Application class. (I have created a class which extends Application and referred to it manifest.) So all these are using single instance of arraylist. A initializes the arraylist since its first screen and others might modify it.
The problem is when I test this on emulator nothing gets broken. But on 'some' phones after 3+ screens of navigation arraylist just clears from the heap. No matter how small size is.

Use a singleton class for your ArrayList

Use singleton design pattern or make your object static
With the Singleton design pattern you can:
Ensure that only one instance of a class is created
Provide a global point of access to the object
Allow multiple instances in the future without affecting a singleton class's clients

Declare ArrayList as static in your first Activity then use it from any it will not broke up.

Related

Android app list structure, and finding Context from a Global class

I have two questions.
Suppose I'm creating an android app with three types of screens:
first, a series of 3 tabs that display information in a list. The type of information determines which tab(s) it's displayed in.
Second, a screen with in-depth detail about a selected list item.
And third, a screen where you can add a list item, which will populate the appropriate list.
What would be a good structure for this program? Right now what I have is a Global class (extends Application) that keeps track of the lists and imports them from a JSON file, an Activity (and accompanying Fragment) for each of the three screens above, and a separate Fragment for the individual tabs.
However, I'm finding that importing the JSON file in the Globals class requires Context that I can't figure out how to get. Before I go any farther, is this a good structure?
And if so, how can I get context in a Global class?
I'm working in Android Studio 3.
Application is a Context. That is, you can just use the current instance – this – wherever you need a Context. (There's no need to call getApplicationContext().)
However, the backing Context will not be properly initialized and attached yet in an Application's constructor. An Application is actually a ContextWrapper, which is a Context subclass that delegates all method calls to a Context field that is created and set by the system upon launch. This means that you cannot call any Context methods in the constructor, as it will still be null there.
As with the Activity and Service classes, though, Applications generally should not have any explicitly defined constructors anyway. Any initialization that needs to be done can be performed in its onCreate() method. The Context field will have been set by then.

Global variable in main activity?

I'm new to Android (and Java) and was trying to find out where to store my global variables that I need in my various Activities, Fragments, etc. so I can easily access them, as well as saving and restoring them when the app is paused (a process that not yet fully understand, but that is not my question).
So the general consensus seems to be to use Singletons by extending Application (like described here).
Now that I played around some more I was wondering what is the reason against declaring variables in the main activity (e.g.final static int myVariable) and then accessing the variable trough MainActivity.myVariable? What is the downside?
Thank you in advance!
First, consider to design your app without needing global variables in the first place. Using global state variables might seem like an easy solution at first, but will complicate testing and maintenance later.
If you absolutely must, the application class is the correct place because it's lifecycle is your application's lifecycle. You can also use regular member variables instead of statics.
If you store variables in an activity class as static variables, the downsides include but are not limited to:
Loading another activity class needs to load all the code in the main activity as well.
Unnecessary dependency from activity to another, creating increased coupling.
statics are harder to mock/inject for example in a testing setup. A thin application object with member vars is easier to mock.
You can make a class that is subclass of Application, and scope of this class will be application wide, so you can access variable globally ( across the activities/fragment)
here you will get related info
there is no downside declaring your global variable as static unless the variable is bound to Context...
it is bad way to maintain static reference for Context (like Activity, Service), Views, Drawables and application Resources...
and some one said in SO (I didn't remember), Android will clear static memory in low memory situations...
For example if you are in "FirstActivity" that calls "SecondActivity", using startActivityForResult, to add a Product do a list, in "SecondActivity" you can CANCEL or ADD this product, if you ADDED it you whant to refresh the Product's list in "FirstActivity" so in "SecondActivity" you can use a "private static final int ADDED = 1" and a "private static final int CANCELED = 2" and pass one of this attributes in the setResult's method of "SecondActivity", before call the finish method, in FirstActivity's "onActivityResult" method you can verify if the "resultCode" is "SecondActivity.CANCELED" or "SecondActivity.ADD" and performe the list's refresh or not.
Just an example..
You can use Application's class (OS save variable in memory while app not destroy) or SharedPreferences (OS save variable to file permanent).

Static methods vs. class extending android.app.Application?

I have a class which extends Application in an Android tabHost app. In the App class, I've been placing methods and variables which I would otherwise need to re-create in every class. One method reads from a DB and stores results in an ArrayList (first name, last name for instance). Rather than re-reading this database and re-creating the code for every tab view which needs the info, I've stuck the method and ArrayList in a class extending Application (myAppClass). This way, by setting up mAC = (myAppClass) getApplicationContext() from any tab view in onCreate() I can reference all the get..() and set..() methods in myAppClass.
My original plan was to use a shared class with static methods and variables but I read a lot of "don't do that" threads so decided to go the Application route. Now, I've run into a situation where I'm trying to use myAppClass in a Project Library but getting errors about android.app.Application cannot be cast to... If I change myAppClass back to static methods/variables (and do not extend Application) things work, but this is supposed to be a big no-no. Is there another way to do this? Not sure if Android passes everything by reference but Would I be better off to re-implement the entire application by passing huge (thousands of objects/members) ArrayLists back-and-forth between methods/classes?
My original plan was to use a shared class with static methods and variables but I read a lot of "don't do that" threads so decided to go the Application route.
The "don't do that" is generally a recommendation against anything in global scope and therefore would cover static data members as well as a custom Application. Both are likely sources of memory leaks.
Now, I've run into a situation where I'm trying to use myAppClass in a Project Library but getting errors about android.app.Application cannot be cast to...
Your manifest in the hosting project probably does not state to use the library's Application implementation.
this is supposed to be a big no-no
Again, static data members are no worse than a custom Application, and in many cases are better.
Is there another way to do this?
Don't use either an Application or static data members.
Would I be better off to re-implement the entire application by passing huge (thousands of objects/members) ArrayLists back-and-forth between methods/classes?
You would be better off having a persistent data model, such as a database. Using static data members as a cache for a persistent data model is OK, so long as you are very careful about your memory management.

Parse an xml once for use across many activities

I'm working with SaxParser to parse an xml. The problem is, I have a few screens or activities coded. At the moment, every time I transition to the new activity from a button press for example, the new activity needs to then parse the xml all over again, so it can populate the screen with the specific content.
Is there a way in which I only parse the xml once through the life of the program?
Thank you.
Sure, just parse it once and store what you want to remember in variables.
More completely, you would probably create a class (or classes) classes that represent with properties the same information that is in the xml document. A constructor of the class would take the xml as an argument, parse it, and populate the properties.
Hope this helps.
Sometime earliear I faced the similar problem the problem is that android only allow some of generic datatypes to be sent across activities and if your datatype is not generic then the only solution that I came across it make it public and static
Basically you want a global data to be shared across activities. Then either you can make it static or just create a singleton class and use it across activities. In this singleton class you can store parsed data.
In android there is facility for extending Application class and declaring it manifest file.
So, in any activity you can do getApplication() and access the single instance of that class.
Again this will be similar to Singleton class.
The Application Framework FAQ has a discussion about how to share data structures across activities. Since each activity usually has its own process, it isn't quite as simple as declaring a singleton object.

Using the Android Application class to persist data

I'm working on a fairly complex Android application that requires a somewhat large amount of data about the application (I'd say a total of about 500KB -- is this large for a mobile device?). From what I can tell, any orientation change in the application (in the activity, to be more precise) causes a complete destruction and recreation of the activity. Based on my findings, the Application class does not have the same life-cycle (i.e. it is, for all intents and purposes, always instantiated). Does it make sense to store the state information inside of the application class and then reference it from the Activity, or is that generally not the "acceptable" method due to memory constraints on mobile devices? I really appreciate any advice on this topic. Thanks!
I don't think 500kb will be that big of a deal.
What you described is exactly how I tackled my problem of losing data in an activity. I created a global singleton in the Application class and was able to access it from the activities I used.
You can pass data around in a Global Singleton if it is going to be used a lot.
public class YourApplication extends Application
{
public SomeDataClass data = new SomeDataClass();
}
Then call it in any activity by:
YourApplication appState = ((YourApplication)this.getApplication());
appState.data.UseAGetterOrSetterHere(); // Do whatever you need to with the data here.
I discuss it here in my blog post, under the section "Global Singleton."
Those who count on Application instance are wrong. At first, it may seem as though the Application exists for as long as the whole app process exists but this is an incorrect assumption.
The OS may kill processes as necessary. All processes are divided into 5 levels of "killability" specified in the doc.
So, for instance, if your app goes in the background due to the user answering to an incoming call, then depending on the state of the RAM, the OS may (or may not) kill your process (destroying the Application instance in the process).
I think a better approach would be to persist your data to internal storage file and then read it when your activity resumes.
UPDATE:
I got many negative feedbacks, so it is time to add a clarification. :) Well, initially I realy used a wrong assumption that the state is really important for the app. However if your app is OK that sometimes the state is lost (it could be some images that will be just reread/redownloaded), then it is fully OK to keep it as a member of Application.
If you want to access the "Global Singleton" outside of an activity and you don't want to pass the Context through all the involved objects to obtain the singleton, you can just define a static attribute in your application class, which holds the reference to itself. Just initialize the attribute in the onCreate() method.
For example:
public class ApplicationController extends Application {
private static ApplicationController _appCtrl;
public static ApplicationController getAppCtrl()
{
return _appCtrl;
}
}
Because subclasses of Application also can obtain the Resources, you could access them simply when you define a static method, which returns them, like:
public static Resources getAppResources()
{
return _appCtrl.getResources();
}
But be very careful when passing around Context references to avoid memory leaks.
Dave, what kind of data is it? If it's general data that pertains to the application as a whole (example: user data), then extend the Application class and store it there. If the data pertains to the Activity, you should use the onSaveInstanceState and onRestoreInstanceState handlers to persist the data on screen rotation.
You can actually override the orientation functionality to make sure that your activity isn't destroyed and recreated. Look here.
You can create Application class and save your all data on that calss for use that anywhere in your application.
I know this is the very old question but using the ViewModel from the jetpack components is the best way to preserve the data between Activity rotation.
The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.

Categories

Resources