Design for survey app - java

I'm very new to java and want to ask for a help about design. I'm going to build a simple survey app for android in java.
Here is how I see the app:
The main page (activity_main) contain LineEdit for ID and two buttons: Login and SignUp. This activity onCreate loads all registered users and questions from DB.
Sign up page (activity_signup) contains several LineEdit fields for user info as well as SignUp button. Also it provides free ID onCreate.
Profile page (activity_profile) contains some user info (as TextView), possibly and a Survey button.
Survey page (activity_survey) contains Question, Answers and two buttons: Prev and Next.
Please mention if something might be improved.
Questions:
Should I store all users and questions as private field in class MainActivity or somewhere else? (Assume that DB is so small that it perfectly fits in RAM)
How can I modify the DB with newly created user from activity_signup? It is rather general question, like how can I access private fields from other activities preserving encapsulation?
I'd like to have a filed like private static User current_user in class ProfileActivity. But I can get the user only from DB, which is private field of class MainActivity. How can I pass the user from activity_main to activity_profile (again preserving encapsulation)?
activity_survey contain answers of different types, e.g. Yes/No; single/multiple choice (+ your variant) etc. How can I handle this in java? My idea is to create an abstract class AbstractQuestion with method fillLayout and inherit several class ConcreteQuestion (here concrete should be replace with an appropriate title) from it which contains implementation of certain type of question. Store all questions in array of AbstracQuestion's. Is it doable in java or is there more right way to do this?
Thanks in advance for any help!

Don't store such objects in Activity. You have several options for data persistence - these are listed here https://developer.android.com/training/basics/data-storage/index.html - of course that does not cover any "external" sources such as databases like Realm or Firebase but let's keep to the basics.
If your data is complex and you think that it would be easy for you to retrieve it using SQLite queries then the SQLite Database is the way to go. You can access it using ContentProvider which can be queried from any place where you have Context.
You can also store it locally on your internal or external storage with simple Serializable classes. Imagine a single object let's call it Database that is Serializable and that contains all the data you need. You could load it in your App startup (like in extended Application class) and store the reference so it won't get garbage collected. Then you can access it from a Application static method you could write to get the reference. It is probably the fastest way to implement a simple storage with fairly complex structure but that is probably not the best if your data is "big". It will increase your App start time (preferably make the load and save operations asynchronous).
If your data is simple you can use SharedPreferences to store "key-value" data. This is a little like second approach but using the Android framework to do it.
The option 2 and 3 require that your data is Serializable or Parcelable. As Android says that Parcelable should not be used for persistence but rather for communication let's skip that one.
You can either make you objects Serializable or translate them to json objects with i.e. Gson library. and store those serialized json objects. Making them serializable directly may be faster approach but sometimes keeping jsons makes more sense.
You can't and you shouldn't have to.
If you wan't to keep your data in static fields move them to extended Application class (make sure you point it in AndroidManifest.xml with specific xml parameter) and access it from there. You can get access to your Application class whenever you have Context via context.getApplicationContext() that you can cast to your custom class.
To tell Android to use your custom Application class use the following in AndroidManifest.xml:
<application
android:name=".YourAppClass"
...>
...
</application>
I am not sure if I get the 4th question right. Basically if you have multiple values you need to store your results in some collection i.e. ArrayList. Your whole questionare could be represented by a Map<Question,List<Answer>> then <- arbitrary class names (these could be enums too)

Related

manage global object or list

I have read many blogs about how singleton are vulnerable in android.so my question is how to maintain such global objects or list in application.i know shared preference is one way but is there any way to maintain such objects or list efficiently.any help will be more helpful.
You can use a file or SQLite database to save data in android app. You can check below links to learn more about saving data in a file or SQLite database:
Saving data to a file is ideal to store long sequences of data that are generally read in order
https://developer.android.com/training/basics/data-storage/files.html
Saving data to a database is ideal for repeating or structured data:
https://developer.android.com/training/basics/data-storage/databases.html
use sharedPreferences, Sqlite database to manage your objects, singletons are not very good, but static variables are more hard to maintain and will make testing the cide more tough, you can use Shared preferences to maintain a global state if the data is not very large, if there is large amount of data then use of sqlite is recommended.
Shared preferences are extremely easy to use, if you have problem using sqlite though you can use orm libraries for android
here's a link to one: http://greenrobot.org/greendao/
If you just want to keep a list as Global until your app is running, then create a new class let's say "Helper" and Initialize a Static List in that class. Now you can access that list anywhere within the app by "Helper.yourStaticListName" and you can also add/remove or get data from the list anywhere within the app.
But if you want to keep that list even when app has been closed, then there are two solutions for that.
First Create a local database "SQLite file" in your app and add/remove or get data from it.
Check this tutorial: http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
Second solution is to convert your data into a JSON and convert that JSON into String and save it in Shared Preferences. And whenever you need it just get the string from Shared Preferences and convert it into JSON and parse to get the data.
One last thing when you are talking about parsing a JSON, then "GSON library" is a good thing to work with.
Here is the link: http://guides.codepath.com/android/leveraging-the-gson-library
Hope this answer will help you.
How about using Android Service?
You can initialize / start it when your application started (and also stop them when your application stopped) and then bind them whenever you need (put and get your object / list).
I believe it will be an efficient way.
From conceptual point having a static variables or service-locators is very similar to having Singletons. Hence, having them as alternatives may not be be correct, if the intention is to avoid the Global state and consequences.
We can change Singleton-classes into instances, which are instantiated only once and injected into the components and methods as needed. We can use a IoC-framework to handle the injection part or do it manually with a factory pattern to construct (we can restrict only one instance creation as well) instances of the classes. This discussion thread gives lot of insights on the problem and various options.
So if I understand your question right, you need to store some global variables all over your application if that's so please take a look at this question
basically you create a class that extends application which would store anything you would like on start of your app and all of them can be accessed trough out the app.
hope this helps.
If you are trying to create a globally accessible object, the first thing you should ask yourself is: Why? Why do you need a globally accessible object? Most of the time you don't, and you can get away with creating an object with a limited scope which is passed around the app.
There are times when you do want globally accessible resources and using a singleton is just one way to accomplish that. According to the Android Docs your data storage options are:
Shared Preferences
Store private primitive data in key-value pairs.
Internal Storage
Store private data on the device memory.
External Storage
Store public data on the shared external storage.
SQLite Databases
Store structured data in a private database.
Network Connection
Store data on the web with your own network server.
Singletons are great, but the do have their own risks based on how they are implemented. Typically developers use this pattern when you are attempting to share a resource within the application, things like Loggers, Print spoolers, etc. There are multiple ways that you can create Singletons in Java, you can use a Lazy Initialization or Static initialization, each has their own pro/cons. In terms of "vulnerabilities", there are issues with whether or not the singleton is thread-safe, who/what can access it, and so on. This is why it makes sense to try and understand the problem you are trying to solve. Personally, I'm not clear on what exactly you are trying to solve, so I can't really elaborate on how this might help or hurt you. All I can say is that the biggest vulnerability is also it's greatest asset, which is that like most global variables, it can be accessed from anywhere at anytime. There can also be an issue whether or not the singleton is thread-safe.
Personally, I think you need to assess what it is you are trying to solve and the pick the appropriate solution. Maybe using a singleton is the correct solution, maybe it isn't. But understanding all your options and the strength/weakness of each one is going to be the best way to solve this issue. Unfortunately, you haven't provided enough context to your problem for me, or anyone for that matter, to give you a solid recommendation.
The best way to manage global objects is not having them at all. Based on my experience, in a lot of cases there are alternative options instead using singletons. There is so good explained in this post
shared preference is good but some time you will feel problem when do some modification make static constant variable in one pojo java class and use this variable anywhere.because shared preference will not change value after use or unless you dint modify .shared preference retrieving and storing is not very unfriendly. if you use constant you can modify easily .only one class you have to hit

Sending non serializable data from service to activity

Notify activity from service
I want to know if it is possible to do what the selected answer in the above post said, when your activity and service are in separate packages. Basically i have an object that is non-serializable (lets say a created view) and I want to send it from my service to my activity. Would be easy enough by using a custom binder, but as i've found out, you cant use custom binders when your service and activity are in separate packages.
I've been pondering this for a few weeks and it has really put a block in my project I am working on.
For those who will ask, I am trying to make a framework that allows "plugins" from other packages. But I am unsure how one would send non-serializable date back and forth between said service and activity.
It depends on the complexity of the object, If the object that you want to serialize is an object that comes from the Android SDK lets say a RelativeLayout or a Cursor I don't see that happening anyway, because those objects contains references to another objects that you don't have access to modify or make them implement the Serializable interface.
If your object is a class that you implemented and all references inside that class are also to another classes that you implementad (or to Serializable/Parceable objects) then sure you can. One way of doing so is, well, making them implement Serializable or making your own Parceable theres plenty of tools to achive this in a quick way like this or this one.
If no one of this answers satisfies you, then tell me what're you trying to send from the Service.
EDIT
Did you try to make a class implement both Serializable and OnClickListener and send it through the intent?
Sounds like you need some sort of Command pattern there.

Handling data on an android app

I'm working on a school project and I'm having trouble coming to a conclusion on how to handle the data it involves.
Basically my app lets you create recipes (cooking) that are stored on the phone.
I don't really have any usable code just yet, so far the structure I thought of is as following:
A class Recipe that represents an individual recipe for manipulation via the app (has all the properties)
A class RecipeList that has a HashMap with all the Recipe objects in it that lets you get a certain recipe by an Id RecipeList.GetRecipe("id") and save Recipes via RecipeList.SaveRecipe(Recipe), it also handles saving to the SD card
The thing is though that eventually I want to outsource saving to a web space (using PHP) which is part of my project assignment, that's why I decided on using a HashMap so I could utilize an Id.
What's the best way to go about it given my current structure? Or is there a better structure for what I'm doing?
This will tell you everything you need to know.

A basic way to have cache/data handled by manager class that my Android Activities can all access?

So what I'm wanting to do is have a few different single manager classes that handle the caching of data that I've pulled down from the internet. I want the data in these classes/objects to be accessible from different activities in my application, whereby any of the activities can manipulate data or call functions as needed.
Eg, I have a UserDatabasemanager where I will store the initial raw JSON data I pull down from the internet and an array of User objects which is a distilled version of that JSON data.
My app at various times will pull data down from the web and will update the User array as data changes. Eg, initially pull down a list of users that fit a criteria. So I then cache all the usernames and IDs into the User objects. Should the application then focus in on a particular user page, it will then download that user's description text and store the new description into User object. (All of which I think I cant do currently with my knowledge of programming)
I've been reading up on sending objects via Intents with Parcelable and Serializable which seems a bit of a round about way of doing things for shared data between Activities.
How to send an object from one Android Activity to another using Intents?
Passing data through intent using Serializable
Since my intention is to use these classes/managers/objects (whatever we want to call them) as single instances I'm not too fussed about following encapsulation to the letter as their job is to provide and update my cache data based on the needs of the Activities.
I'm still very green with all this Android/Java stuff, but it seems this sort of thing would be fairly straight forward in C/C++ with pointers. It seems that even if I was programming directly with Java I could pass around references to objects fairly easily, but the structure of Activities seem to be in such a way that it doesn't lend itself to easy passing data around in my own program?
One easy (but not great) way to achieve this is to use the Android Application class to store (the singleton) instances of your managers. You can always retrieve a reference to your application by calling getApplication() on any activity.
You need to provide your own implementation of the Application class so that you create the managers in the onCreate() method. You should also create strongly typed getters for your managers.
Also, consider what you need to do for the system callbacks the Application may receive such as onLowMemory().
So what I ended up doing in the end is making a Globals.java file with the following contents
public class Globals {
public static ArrayList<User> userObjArray = new ArrayList<User>();
//Weird magic class stuff
private static Globals instance;
private Globals() {
}
public static synchronized Globals getInstance() {
if (instance == null) {
instance = new Globals();
}
return instance;
}
Then whenever I wanted to use data from the Globals I would do something like...
Globals.getInstance().userObjArray
This seems to be working exactly how I want it to. Its not great for encapsulation, but that wasn't the goal for what I needed to get done.
I think you should use android service and create binders in your activities.
http://developer.android.com/guide/components/services.html

Global Objects accessible throughout Android application [duplicate]

This question already has answers here:
How to declare global variables in Android?
(17 answers)
Closed 2 years ago.
I have an application that uses a custom class. When the app is started I populate an instance of this class in the main activity with all the data it will hold.
Basic data is then shown in a ListView from which you can select a ListView item to see further information displayed in another Activity.
Currently, I am having to pass the data that is relevant to the new Activity to it by using:
intent.putExtra("NAME", value);
I want to implement a ViewPager so the user can easily switch between ListView items. Therefore the currently use method isn't very good as I only have the data for one entry at a time and would need to get back to the original Activity to get all the data again.
Is there a way to have my class objects globally available ANYWHERE in my application? I feel my applications code is getting bloated as I am overcoming these issues in bad code methods.
I've just looked into using:
MyApp myapp = ((MyApp)context.getApplication());
but this won't work unless I can pass the context around, which I'm not sure how to do??
In C# you'd create a static class that could handle this....
Thanks
Neil
You could have:
a static class holding your data (available until the process is killed)
a local service offering access to your data
the application class holding your data
a database mechanism to persist your data (in that case you'd simply pass IDs as intent extra)
All those options are more or less valid, it also depends on what you do with your data, where it comes from, ...
I think you are looking for a Singleton object. Create the custom class that holds all the data as a singleton object and access its data from anywhere in the code. Also, as this data may not be directly related to the UI, you should not be associating it with an Activity.
HTH,
Akshay

Categories