On example we have an app that tracks Taxi drivers, a taxi driver log in into application and pick an order to drive for given customer.
In this case we have an Order class that represents a lot of data, it's very important to have access to this object from anywhere while still being able to modify it.
From now we can:
pass it by putting extra data to an intent, but it's not something
that makes code readable, in some cases it won't be a solution
deserialize the object into json and store it into cache, we still
need to constantly update this value which is a headache when more
complex objects are in game, one mistake and god knows when the
mismatch happens
store it into class that extends Application, this
is approach I am testing right now, but I am having doubts about this
as when app crashes / android will release app resources randomly, I am in need to restore given object state using
black magic with cache anyway
This is a problem that I believe is shared across many applications, like Spotify's current playing track, etc.
Are there other approaches?
Try using a sqlite database. In this case, you can access your data anywhere from your app if you create a robust GetOrders API method yourself.
Here is a tutorial of creating a database.
In this case, you will never lose any data if app exits or crashes. Also, it really makes no difference compared with caching your data in memory.
Related
Is there a better architecture that we can follow other that making these fields static(bad for performance) or storing in Shared Preference.
Either use Shared prefs or a database. Both are optimized for quick and (more or less) safe access. It might be worth your while to read about Architecture Components, Room (or others such as ObjectBox, Realm, etc) and repository pattern.
Android Jetpack would be your best option. Check out the documentation on Data Binding, it would allow you to access fields like user_id without writing tons of boilerplate java/kotlin code, by injecting the data directly into you xml code. Here's the link: Android Jetpack Data Binding
There is nothing wrong in saving two/three Strings as static variables, In fact it is the fastest way to get repeatedly used variables. I prefer Application class to do so(static variables of Application class), but the issue is if your app happens to crash for some reason, application class is recreated and app starts from the previous activity, alas your static variables are long gone, be aware of this pitfall
Depends on how/when you are using these static elements.
A few application global variables like userSession object might make sense to store in the MyApplication file itself and made exposed throughout the app so you confirm it is valid when app returns from background each time for example.
SharedPreference is not a great place to store secure elements as it is on file storage in unencrypted xml format which rooted phones and others may have access to get to.
Database is a fine option, but it requires more code bloat and requires a database connection and query everytime you want to use the token if you don't plan to store it in RAM.
Another option is a singleton class that is meant to store your necessary application elements like FirebaseHelper for example that could populate into RAM on app startup and utilize your variables throughout the application life.
So really depends on your app needs. You can also use a SecureSharedPreference tool. There are a few open source options out there for this that you can just include in your project that encrypt the xml elements for you if you prefer to use the xml for storing these items.
If it was me, I would either you a secureSharedPref if it was simple things like userId, Token, or things like that that are fairly harmless. Of course it will encrypt them, but worst case if they got your token, they could make a few API calls if they knew what they were doing, unlikely. Now storing things like password, bank info, medical records, or anything else sensitive definitely should be in a Database. In fact, I would go one step further and layer it with SQLCipher.
So long story short is it depends on what you are storing and the risk assessment of it's content being accessed and each app will be different.
Absolutely nothing wrong with storing some static variables or singletons. Anyone building an enterprise level application will have a fair amount of statics in their application if it is architected in a good way.
In my application, I have some data to display in the dashboard which are coming from the sqlite db. But when I put the app to the recent app and open the app from the recent app list on next day, those data don't display and showing the error message (that I set to show when there is no data in the sqlite).
To give a better idea about my issue, those are the basic steps.
Install application
Open Application
Navigate through pages
Keep the device
Open Application on Next day
Inspect the behaviour of Dashboard(No data showing)
I think android may auto kill the apps in the recent app.isn't it?.
How can I solve this issue?.
If the data that you are storing are only with respect to your Activity and other classes, Android will clear off data as per priority for availing memory.
This is applicable to static variables also. Resolution for this will be storing the data using Parcelable interface.
Store data either using Parcelable or in Sqlite.
Retrieve the same when the Activity/Fragment is loaded again
Use plugin's available to generate these objects for ease of programming like android-parcelable-intellij-plugin-kotlin
For sample implementation use this reference StackOverflowLink
I don't know how the app flow have been designed since there is no source code, but the following lifecycle will help you figure out the point where you are losing your data (I am assuming you are talking about the unsaved data).
Based on this, you might have to implement the onPause() and onResume() accordingly.
I'm developing an app that downloads ParseObject's data from server and populate a ListView in Fragment with it.
I read about downloading data by Service and after it's done (some kind of listener?) it would update Fragment and be accessible until user leaves the app (which is fine by me).
On the other hand - I can just store it in Bundle and retrieve it every time I get back to that Fragment, but then I'd need implement Serializable which in this case can be cumbersome: like here
Fragments are held by DrawerLayout so it's really irritating now to see loading bar everytime You change to that Fragment and I'm looking for a solution to change that to improve UX.
What do You suggest? Which approach would be better in that situation? Maybe there are things that I should be aware of before attempting to use any of these?
I think it depends on how often the data is changed on the server.
If only daily/weekly the solution must differ compared to if the data is changed every mins/hours.
If the data is kind of static then you can download it only once, and save it to SharedPreferences, or to a seperate local file or DB.
If it changes kinda often, I'd suggest to use bundles or in memory objects, so when the user reenters the app the data should be downloaded again.
The solution i'd use would be to simply convert the entire list of data to JSON, and then save it in SharedPreferences. This allows for easy reuse of the data when the user goes back to that fragment.
As you aren't saving the data across app close/reopen, a local database is not needed.
I am making an app that will let user keep notes - simple text entries. I want to persist these to the backend and Parse.com seems to make it easy. While going over their documentation, I came across this:
There are a couple of side effects of enabling the local datastore
that you should be aware of. When enabled, there will only be one
instance of any given ParseObject. For example, imagine you have an
instance of the "GameScore" class with an objectId of "xWMyZ4YEGZ",
and then you issue a ParseQuery for all instances of "GameScore" with
that objectId. The result will be the same instance of the object you
already have in memory.
Say that my class is called NoteEntry. Since the user will create a number of notes, there will be a lot of NoteEntrys. Does the side effect mean that only a single NoteEntry can ever exist in the database?
and
Another side effect is that the current user and current installation
will be stored in the local datastore, so you can persist unsaved
changes to these objects between runs of your app using the methods
below.
I don't even know what that means. What is it saying?
Doc: https://www.parse.com/docs/android_guide#localdatastore
No, that's not the side effect. You can still be dealing with lots of Parse objects, it just means that there will be only one copy of each different object. If you had a NoteEntry object in variable x and later query and that same object is returned, it will be equal to the object in x and not a separate copy of the object.
I have one app which authenticate user to access internal activity, App is having several activity which gets data from previous activity
So I am bit confused on activity life cycle
I read Bundle data into local variable in activity OnCreate and reading DB in async task based on that data. this DB data is displayed on my app.
Now if I switch to another app, will my app have that local variable/Static variable data (read from DB data) with them,
I have SingleInstance class which keeps user ticket etc informations, Is that variable keeps in memory of app if we got phone call in between.
I am bit confused on this part.
As document suggest that you need to store unsaved data in shared preferences.
It would be good if someone highlight on that..
Well, first of all you need to make sure you understand the difference between a new app and a new activity according to the sentence:
Now if I switch to another app, will my app have that DB data with them after switching back to my app
If you actually mean different apps, the answer is "NO in another app(in case is your app too)" you cannot have access to another application DB (at least not directly), the only way is if that application implemented a content provider to share its data with another application, by default android applications are like sandbox and do not share any information with other apps unless specifically declared, there's another rules between two apps signed with same key but that's a different story and a huge advance topic not related to this question...
In case that you " mean go to another app (not mine) and then try to use it from MY app again " the answer is "YES", the information in the database is accessible among all the building components like "activity, service" that belong to the same application, information in database is persisted even after closing completely the app (and so is shared preference), but there's a huge different between shared preference and DB, and knowing when to use one or another differentiates between good and excellent developers, golden rule (but not the only or the best) is that, DB is used for complex queries and relational data that needs some sort of preprocessing or postprocessing to get the proper values, mean while shared preference is just a "key/value" map that persist in the application context
Hope this Helps.
Regards!