I have a NFC tag and I have to read from it a text, and save this text some where to use the parameters in it in many activities and fragments.
this parameters I should be able to delete or overwrite it when a user decide to exit the program or to read another tag.
I didn't like the idea to transfer this parameters over the activities since they are constant in the whole session for example the ID number of the tag and the manufacturer of it.
I thought also to creat a file in Assets and read it every time, but I thought there should be better way to solve this problem.
There are several ways to how you make the values accessible throughout the project.
Using Shared Preferences:
You can use shared preferences, where you can create variables for your fixed values such as TAG_ID and MANUFACTURER_ID. Every time you tap a new card you can update them, or anytime you expect them to be changed.
Using a Model Class:
You can also create a Model Class (May be Singleton as well) which holds the TAG_ID and MANUFACTURER_ID. Initialize the object of this model class every time there is new Tag tapped. You can also access/change them anytime using getters and setters.
Using Static variables:
You can define static variables to store your desired values and you can simply access them wherever and whenever you want to. This will workout only with less numbers of variables. Increased static variables could affect the performance.
Related
I'm new in programming for Android so maybe my question will be very easy to solve but still. I'm trying to make an array of different data types :
I have to add there :
int number
String name
int number_2
int time
int total
And my question now is how to implement it in easiest way, and how to get data from it. In case that I have to get a different records for this variables and store it into list .
Also have a question about way how to keep all values which I handle inside of my array.
I have to keep it because in my program I have to go back to other activities go forward to another and again collect data and add it to my array.
What will be the best and easiest solution ?
Thanks in advance for help
You could create the Array as an Array of Objects. All other classes are derived from Object, so you'll be able to store all types of objects in your Array. However, you would have to check the type of an object you get from the Array, before you'd be able to safely interpret as an object of a specific class. Moreover, you would have to use Integer instead of int.
If all (or at least multiple) of your elements you are intending to store in the Array are belonging to one (physical) entity, you could create a custom Class that holds its own properties as class members, and fill your Array with a list of instances of this Class.
Moreover, if you plan to add elements to your Array, you should use a List instead, e.g. an ArrayList.
As for retaining your data, you would have to either store it in a database, or save it to a file. In either way, you will have to save it upon close of the Activity, and load it again once the Activity starts
To pass the data across activities you will need to pass them using objects you can store in an intent. Seems like the best way to handle that is to either create a PREFS file to store the data or to create an object that extends Parcelable like here:
https://stackoverflow.com/questions/18593619/android-parcelable-object-passing-to-another-activity
Parcelables are preferable assuming you need all the data in a single object, you do not want to "putExtra" a bunch of fields and you also want to be sure data can pass from one activity to another. Otherwise, a simple Util class that reads and writes to a PREFS file is the way to go:
android read/write user preferences
A database is always another option, but seems well outside the scope of your question.
I am building an application and use labels in the following areas.
1. Component Names (TextView, Buttons etc)
2. Buttons in alert boxes
3. Parameters to AsyncTask
4. Key names in Intent extras
5. Log tags
I have got strings.xml files to store and use labels. I am using using it for category 1. What do you think is the best option for others?
res/strings.xml or
Constants class ?
I'll suggest to you what I normally do:
For everything that the user will read on the screen or be referenced in anyway from a XML layout, use strings.xml. I reckon that includes your 1 and 2. But remember that for AlertDialogues you can also use android.R.string.ok or android.R.string.cancel, etc; that will vary from use to use.
Also for project config values, or API keys, you could have a config.xml with String, Integers, etc. Something that makes easy to later on change those values without diving into the code.
For AsyncTask, it varies a lot of what work it is doing, but usually a network, DB or disk operation, and I try to include private static final String URL_PT1 = "http://..."; etc, in the classes themselves, as they are the only interested in knowing that address (or DB columns, or file prefix)
For key names (both in Intent and Fragment arguments) I use private static final String KEY_VALUE = "renjith.Key.MyClassName.VALUE"; and then create a public static Bundle getIntentExtras(String value) inside that class that will properly allocate the value in the extra. That's because only that one class needs to know about it's KEY values, there's no reason to make those public accessible, that will just create errors for outside classes doing it wrong.
For Logs (5), create on every class a private static final String TAG = "Renjith.ThisClassName"; (and for Fragments make the TAG public to be used in transactions). That way you can create a filter in LogCat Renjith.* and you can easily identify from where this log is coming from
edit:
For sharedpreferences it depends:
for GlobalSharedPreferences I would create one class to handle them with static set/get methods that must receive Context and all keys private static inside that class.
For local shared preferences (that only one class is interested in saving/retrieving) I would handle in a SharedPreferences file with the same name as that class and all the keys as private static inside that one class.
Again, same philosophy, only the classes that really need to know about those details will know about them, and abstracting to the rest of the classes with direct method calls.
Is there any disadvantage in transferring values from Activity A to Activity B with static fields of a third class instead of the ExtraBundle?
In my application, sometimes I have like 15 - 20 values that I need to transfer between two Activitys. In my oppinion, it is more lucid solving this with static fields from a sort of TransferHandler.
At the moment, I have one disadvantage in mind: When a value is not put into the Extras before starting Activity B, I will get an Exception. Solving it with static fields, it it possible that I forget to assign a value, and if that value was assigned before from somewhere else, it might be that a wrong value is used in Activity B. Nonetheless, I think this is a "programmer problem" and not a "program problem". So are there any further minusses or am I free to choice a way? How's with the performance of the two variants?
First of all, if you plan to use static values, you should use your Application class to do this (because Android system assures you that it is a true singleton)
Thus, you can store your datas in attributes of your custom Application class, and use specific methods to store and get these values.
This will ensure you can't "forget" any values.
Also, with 15-20, I will strongly advice you to make a specialized POJO class to store all this...
I think the biggest disadvantage with using static classes for passing information in android is that static fields and objects can be cleared by the system at any time. That means that any static non final value can ALWAYS be null.
So it will probably work fine most of the time, but if you don't make sure to handle these null situations and your users start using your app they'll get a null pointer exception crash once in a while because the system decided it needed that memory stored in those static fields.
The best way for passing data between activities is by my opinion by using Intents, see here for a good example. Alternatively use a database or the the sharedpreferences.
Google also have a good read about pass data between Activities/Services here.
You cannot use a third class to transferring values form one activity to other. Here is the problem with it. You create one object in the activity-a then you store some values into it. Then after for using the values you need to create one more object in the activity-b then the object created in activity b will not be having the values you assigned in activity-a.
You can use SharedPreferences class to store valuo of variables:
SharedPreferences settings = getSharedPreferences("shared_pref", MODE_WORLD_READABLE);
SharedPreferences.Editor editor = settings.edit();
// With editor you put data
editor.putString(firstName, "John");
editor.putString(lastName, "Smith");
editor.commit();
You can access this data in all activities:
// With settings you access to data in different activities
SharedPreferences settings = getSharedPreferences("shared_pref", MODE_WORLD_READABLE);
String firstName = settings.getString(firstName, null);
String lastName = settings.getString(lastName, null);
I am new to android development (and also a java newbie) and I noticed that when I switch between views I noticed that any variables declared as static in the view class retains its value but the rest are gone. So I have the following questions if some one is kind enough to answer --
When to use static for variables if any?
If I want to retain the state of say my game between these switches (say to see the score or something), what is the way to do it? Is it by using static variables in the class to store everything? If so how do I reset the variables for a new game?
When to use static for variables if any?
Static variables should be use when multiple activities needs access on it. In other words, if you think your variable has global usage, then setting it as public static may help.
If I want to retain the state of say my game between these switches (say to see the score or something), what is the way to do it? Is it by using static variables in the class to store everything? If so how do I reset the variables for a new game?
You need to override onSaveInstanceState and onRestoreInstanceState to save and restore the values of your variables. A tutorial on how to use it can be found here: http://android-er.blogspot.com/2011/09/onsaveinstancestate-and.html .
I have an application which has some static variables.
These variables are stored in an independent Class named DataContext.
These variables are initialized from raw files at the application start (a method named DataContext.initConstant() is called in the onCreate() of MyApplication which extends Application).
(EDIT : the initConstant method use an AsyncTask to load this data from files).
When my application comes to the background for a certain time or when my application used to much memory, these static variables become null.
How can it be prevented?
If not what should I do with my static variables?
I have other data which are stored in static variables to be used across different activities, but I clear them or pass them to null in the onLowMemory() of MyApplication.
What is the best way to keep some data accessible between activities if these data are too big to be serialized in an Intent, a database can't be used (for whatever reason), and can't be stored in files through serialization either?
You can't. Android needs to free up memory from time to time. Imagine if all applications had a ton of static data that is supposed to be resident forever - how would you fit that in memory? It's a mobile phone. It doesn't have virtual memory.
(and 3): Anything that is intended to be persistent needs to be stored, either via SharedPreferences, a Sqlite database, or a file.
Most likely the issue is that your application is being killed while it is in the background, and then recreated when you come back to it. Check out the Activity Lifecycle documentation on when this might occur for a single activity. You need to make sure that you move anything stored in memory to more permanent storage at the correct point in time to avoid losing that information if the app gets killed.
I'm not sure what exactly you are storing, but it sounds like using Shared Preferences might work well. This page on Data Storage explains a number of different ways of more permanently storing data, including Shared Preferences.
If you weren't using raw files, I'd advise initializing when the class is loaded.
For instance,
public static Map<?,?> myStaticMap = new HashMap<?,?>();
static { //fill myStaticMap }
You do have some bigger concerns to worry about if you are loading files that way. For instance, what about I/O errors, or latency issues? You will get warnings in gingerbread (if you enable them) for doing I/O in your main thread. Perhaps you should have an object to retrieve these values instead of a class with static fields. (perhaps with a static cache, although you should synchronize on it before checking/changing it)
I assume this is a data cache problem.
Storing data in static class is not guaranteed to work when user swap apps often. Android system will reclaim any background activity when memory is low. Static class is definitely among this category.
The proper way to do it is to use sharedPreference to persist cache data.
You can create your own getter and setter of the data you want and wrap it around sharedPreference object. When you access using getter, you should always check if the value is empty or expired. You can store an update_time when using setter.
For activity specific data, you can just use getPreference(permission), if you want to share data across activities and other applications components, you can use getSharedPreference(name, permission).
Normally, the permission will be MODE_PRIVATE such that the data can only be accessed within your application.
You should group data and store in difference sharedPreference object. This is good practice because when you want to invalidate that group of data, it is just a matter of one liner.
editor.clear(); editor.commit()
If you want to cache complex object, you should serialize it. I prefer JSON format. So you need some conversion mechanism in place. To do this, I will create my data object class extending JSONable class. JSONable class will have toJSON() method and readFromJSON(). This is convenient when restore and serialize data.
I store a User object and a Client object in my static scope. I have noticed from time to time the reference becomes null. So now in my getters I check to see if this value is null and if so I restart the app.
Intent i = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(i);
I could have also chosen to reload the Client because I store the Access Token in prefs however I do so much initialization that I decided restarting the app would the best idea.
In your onResume() method you could query the static data to see if it is present and if not, load it back in again.
Instead of using the static variable u can use the shared preference for storing the value.
Note: for shared preference also you should not give heavy load.
I have solved this problem by having the super class with getter and setter function for storing and retrieving shared preference variable.
All class in my application extended the super class instead of activity.