I have created one activity that creates user profile and stores its information like name,id, profile pic etc.
This information is unique and should be use in all activities in application.
I want to know which is best way to create a common object that stores all information and use it in all activities.
I have read about bundle and JSON but can't understand it how to use it.
Please help me as to what option should I choose. I have done a lot of reading but not sure as of now. Please help me with whats the standard thing to do and what would be better.
You can use Application class for accessing same object across many activities.
public class TestApplication extends Application {
//Object declaration
public TestApplication () {
// TODO Auto-generated constructor stub
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
//setter getter for object
}
Now in your Activity:
//after setContentView
TestApplication testAppObj = (TestApplication) getApplication();
testAppObj.setSomeObj(myObj);
//retrieve as:
someObj = testAppObj.getterMethodOfObj();
You must register your Application class in your manifest file just like you register your activities:
<application
android:name="com.pkg.test.TestApplication " />
Hope this helps.
You can create your custom Application (like others said) and then you will have a global access to this information but I think this is not a good design because your activities will be tied to this Application implementation (you will not be able to use this activities in a different App).
I suggest you to implement a Service and use this Service in all the activities.
Check the next article to create a background service which will be active for all the activities:
https://developer.android.com/training/run-background-service/create-service.html
Best way to implement this is to save data in Prefrences and retrieve whenever required. To simplify this you can directly store an Object in prefrences and get that object whenever required.
To save object you will require GSON library to be added in your libs folder and the you can conver any object to string and store anywhere you want like this.
Object-->>String >>>
Gson gson = new Gson(); String json
=gson.toJson(Object);
Getting object back
String -->> Object >>> Gson gson = new Gson(); Object obj
=gson.fromJson(json string);
The above method will return in a persistent storage and you won't keep memory occupied all the time.
Static variables can be freed by system on memory requirement, hence not recommended.
The Application way is the best, but if you want to check here is the official list of common ways to do that.
Related
I have read some articles about how to use/extend the Android Application class but I am still kind of unsure if I can use it for my needs.
In my Application, on startup, i read a JSON configuration file. This configuration file contains some basic infos about an external device. Because I need this infos in several other fragments/activities I simply store an object representation of this json file as a member variable of my Application class.
public App extends Application {
private ConfigurationContainer configuration;
...
getters / setters
}
When I need it i call getApplication().getConfigurationContainer().
Is this OK for my needs?
Yes, It is ok.
Follow this steps.
1.Override onCreate() method and load all the json configuration in this method.
public App extends Application {
private ConfigurationContainer configuration;
public void onCreate(){
super.onCreate();
// load json configuration.
}
// getter setter
}
Declare this class in manifest file.
<application android:name="com.packageName.App">.
Use this configuration in all your activity.
App ap = (App)getApplication();
ConfigurationContainer conf = ap.getConfigurationContainer()
Yes it is reasonable to store globally scoped variables (or objects) in your Application class. You should be careful that you are not storing too much data here, as it will consume memory that is never recovered as long as your app is running.
Your concept is fine, but there are some nuances about using the Application class in this way, it is suggested that you create a Singleton class (instantiated by your Application) to store values like this.
Here is a great SO related to this: Android Application as Singleton
Let's assume I have a class MainActivity.
This contains a number of objects stored in fields, such as instances of Player, Enemy, Level, etc. Each of these objects needs to be able to refer to every other object.
What is the best way to go about this?
Make these fields static, and refer to them accordingly, i.e.
MainActivity.player.setHealth(0);
Create getter methods for each field, and simply pass each object a reference to MainActivity, so that they can call these getter methods, i.e.
mainActivity.getPlayer().setHealth(0);
Pass each object a reference to every other object, and store these references in fields within each object, so that they can be referred to directly, i.e.
player.setHealth(0);
Not a real answer but just to give you some tips.
Your Player should be like so:
public class Player
{
private static Player _player = null;
int _health;
...
public static Player getInstance()
{
if (_player == null)
_player = new Player(...);
return _player;
}
public void increaseHealth(int amount)
{
_health += amount;
}
}
Then in any part of your application when you need a Player you can do:
Player p = Player.getInstance();
and you will get the same player all the time. You can do a similar thing with your level class as only 1 level will be active at any one time.
However the Enemy class will need a different approach. I would make a List inside the Level class and get at them like so:
Level l = Level.getInstance();
List<Enemy> enemiesOnLevel = l.getEnemies();
// do something with them
Have a look in the Android docs here: http://developer.android.com/guide/faq/framework.html#3. There is also the possibility to serialize your object into primitive datatypes and pass those within your Intent to the new Activity.
A couple more options to share objects between activities are to use parcable, which I think is probably the highest performance method, and shared preferences.
In my app I used to learn (the little I know about android programming), I used gson to serialize the object to json, then stored it in shared preferences in activity A , then recreated it from shared preferences in activity B, and then stored it again.
I want to make some data available between some activities, just like a shopping cart on a website would do.
This data would probably be a collection of strings maybe a list, a map or something like that. Each item should have associated a id, quantity, type, and a text note (about last one isn't sure yet)
The point is that it doesn't need to be persistent after session ends, and this data will be deleted and recreated completely many times in a whole session.
The question is :
Is the best choice to use a SharedPreferences?, a database?
Thanks!
Even better choice would be some singleton java collection ( map or list ) located via factory object. Just store your cart there and do not bother with database or preferences at all
In case you decide to use preferences, I can recomment my small databinding library:
https://github.com/ko5tik/andject
the simplest way is to use a class with public static variables declared and jus set them from any activity and the retrieve that saved value in any other activity just by calling through a static refrence i.e MyContantsClass.StaticVar1 like
class MySessionVars
{
public static int MyVar1;
}
In first Activity
{
MySessionVars.NyVar1=10;
}
and from any other activity
{
Var = MySessionVars.NyVar1;
}
this is easiest way and will retain vars untill app is closed
You can use Gson (by Google) to send and receive any data btw activities, even class object.
Send: (FirstActivity)
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Gson gson = new Gson();
intent.putExtra("CustomClassObject", gson.toJson(object));
startActivity(intent);
Receive: (SecondActivity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Bundle extras = getIntent().getExtras();
if (extras != null)
{
Gson gson = new Gson();
CustomClass object = gson.fromJson(extras.getString("CustomClassObject"), CustomClass.class);
}
//...
}
SharedPreferences is great for storing simple key/value pairs and small amounts of data, however, I imagine your shopping cart object(s) might be a bit more complicated than that. For that reason I would probably use a SQLite database. If you don't have complicated data though, and you just want to store some simple stuff then Shared Preferences should do.
Use Bundle or Intent.
I wouldn't recommend using database for this purpose. Database needs to be properly opened and closed. Where data is passed around activities, it can get messy which activity should be the last to close the database, and may cause a leak. If you are just passing these data from one Activity to another, create a Bundle, attach it to Intent as you start the next activity.
SharedPreferences are key-value pairs whereas database in Android is SQLite both persists after session. You can do any number of operations on SQLite database and use the same file during next session also.
You can put up comments to my answers if you need more clarifications for your particular use case.
People may talk about making global data or storing values in sharedpreference but according to my experience, the simplest way is to just create a separate class with your variables or arraylists declared as public static then use them throughout your project by just referring to the classname.variable name.
class global
{
public static arrayList<String> my;
}
in any of your activity
global.my
This is the simplest method i found so far!
I'm trying to persist data objects throughout my Android app. I want to be able to access an object in one activity, modify it, save it, navigate to a new activity, and access the same object with the updated value.
What I'm essentially talking about is a cache, but my data objects are complex. For example, ObjectA contains ObjectB which contains ObjectC. Does anyone know if a good method, tool, or framework for persisting complex objects in Sql?
Put a static field in a subclassed Application. Also inside your manifest, put:
android:name="MyApp" inside your application tags.
Also to access from other files, simply use:
MyApp myApp = (MyApp)getApplicationContext();
See here How to declare global variables in Android?:
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();
...
}
}
You could use an ORM framework, like OrmLite for mapping objects into sql, but it may be an overkill for you situation.
You could also make these shared object Parcelable and pass them between the Activities thru the Intents.
You could also save these objects into the SharedPreferences, so each Activity can access them whenever they feel the need to it, and the objects are also persisted this way. This may mean more IO access though, so take that into consideration as well. You could use e.g. Gson to serialize the objects more painlessly for this.
These are the solutions I'd consider. But whatever you do, don't put this common object into some kind of "standard" global static variable, like using a custom Application class, static field or any implementation of the Singleton pattern, these are really fragile constructs on Android.
Why don't you use a JSON serialization mechanism ?
In association with a static access to your objects you can easily build a lite-weight database with some basic functionnalities:
loadObjectsFromCache
saveObjectsInCache
getObjects
You can also store your objects in differents files, and use a streaming json parser like this one: http://code.google.com/p/google-gson/
It's the same that this one: http://developer.android.com/reference/android/util/JsonReader.html
but can be used even if your application api level is inferior to 11.
It use less memory than the basic DOM parser:
http://developer.android.com/reference/org/json/JSONObject.html,
but with the same speed.
This question already has answers here:
How to pass an object from one activity to another on Android
(35 answers)
Closed 9 years ago.
I need to be able to use one object in multiple activities within my app, and it needs to be the same object. What is the best way to do this?
I have tried making the object "public static" so it can be accessed by other activities, but for some reason this just isn't cutting it. Is there another way of doing this?
When you are creating an object of intent, you can take advantage of following two methods
for passing objects between two activities.
putParcelable
putSerializable
You can have your class implement either Parcelable or Serializable. Then you can pass around your custom classes across activities. I have found this very useful.
Here is a small snippet of code I am using
CustomListing currentListing = new CustomListing();
Intent i = new Intent();
Bundle b = new Bundle();
b.putParcelable(Constants.CUSTOM_LISTING, currentListing);
i.putExtras(b);
i.setClass(this, SearchDetailsActivity.class);
startActivity(i);
And in newly started activity code will be something like this...
Bundle b = this.getIntent().getExtras();
if (b != null)
mCurrentListing = b.getParcelable(Constants.CUSTOM_LISTING);
You can create a subclass of Application and store your shared object there. The Application object should exist for the lifetime of your app as long as there is some active component.
From your activities, you can access the application object via getApplication().
This answer is specific to situations where the objects to be passed has nested class structure. With nested class structure, making it Parcelable or Serializeable is a bit tedious. And, the process of serialising an object is not efficient on Android. Consider the example below,
class Myclass {
int a;
class SubClass {
int b;
}
}
With Google's GSON library, you can directly parse an object into a JSON formatted String and convert it back to the object format after usage. For example,
MyClass src = new MyClass();
Gson gS = new Gson();
String target = gS.toJson(src); // Converts the object to a JSON String
Now you can pass this String across activities as a StringExtra with the activity intent.
Intent i = new Intent(FromActivity.this, ToActivity.class);
i.putExtra("MyObjectAsString", target);
Then in the receiving activity, create the original object from the string representation.
String target = getIntent().getStringExtra("MyObjectAsString");
MyClass src = gS.fromJson(target, MyClass.class); // Converts the JSON String to an Object
It keeps the original classes clean and reusable. Above of all, if these class objects are created from the web as JSON objects, then this solution is very efficient and time saving.
UPDATE
While the above explained method works for most situations, for obvious performance reasons, do not rely on Android's bundled-extra system to pass objects around. There are a number of solutions makes this process flexible and efficient, here are a few. Each has its own pros and cons.
Eventbus
Otto
Maybe it's an unpopular answer, but in the past I've simply used a class that has a static reference to the object I want to persist through activities. So,
public class PersonHelper
{
public static Person person;
}
I tried going down the Parcelable interface path, but ran into a number of issues with it and the overhead in your code was unappealing to me.
It depends on the type of data you need access to. If you have some kind of data pool that needs to persist across Activitys then Erich's answer is the way to go. If you just need to pass a few objects from one activity to another then you can have them implement Serializable and pass them in the extras of the Intent to start the new Activity.
Your object can also implement the Parcelable interface. Then you can use the Bundle.putParcelable() method and pass your object between activities within intent.
The Photostream application uses this approach and may be used as a reference.