I am trying to pass the complete arraylist from one activity to another.
i have tried like this way..
arraylist=new ArrayList<HashMap<String,Object>>();
Intent i= new Intent(ListActivity.this,search.class);
i.putExtra("arraylist", arraylist);
startActivity(i);
Could somebody help me out #thanks
This will not work because the Object class in Java is not serializable. See this question for an explanation as to why.
The Intent.putExtra() method requires a type that implements the serializable interface, Object does not implement this so consequently it will not work. I would suggest rather than having a HashMap<String,Object> you replace the Object with a more specific type that implements the Serializable interface. See this tutorial for how to do this.
UPDATE
If the data you are passing is large there could be a fairly significant overhead associated with serializing and deserializing. Consequently it might be worth using a Static Singleton class to store the arraylist. The code sample below shows how you could implement this:
public class DataStore {
private static final DataStore instance = new DataStore ();
private arraylist = new ArrayList<HashMap<String,Object>>();
//Private constructor
private DataStore () {}
//Class is only accessible through this method
public static Singleton getInstance() {
return instance;
}
//Accessors for your data
private ArrayList<HashMap<String,Object>> getArrayList()
{
return arraylist;
}
private void setArrayList(ArrayList<HashMap<String,Object>> value)
{
arraylist = value;
}
}
For reference here is a tutorial on static singletons.
Related
I hope that we can pass data between android application components
by following ways.
1.we can pass data using intent object,
2.we can implement serializable , parcelable interface and pass objects by using intent,
3.we can create a new class by extending Application class, to access global members from anywhere
the android application,
4.sharedpreference ,
5.sqlite.
Are there any other mechanism to send data between android application components?
Another option is create ApplicationPool.
Follow the below steps:-
Initiate the ApplicationPool :-
ApplicationPool pool = ApplicationPool.getInstance();
modify the data on details page and add to pool
pool.put("key", object);
get the modified data on list page from pool
Object object = (Object) pool.get("key");
important notes:- notify the listview or gridview after getting the data
ApplicationPool class file
public class ApplicationPool {
private static ApplicationPool instance;
private HashMap<String, Object> pool;
private ApplicationPool() {
pool = new HashMap<String, Object>();
}
public static ApplicationPool getInstance() {
if (instance == null) {
instance = new ApplicationPool();
}
return instance;
}
public void clearCollectionPool() {
pool.clear();
}
public void put(String key, Object value) {
pool.put(key, value);
}
public Object get(String key) {
return pool.get(key);
}
public void removeObject(String key) {
if ((pool.get(key)) != null)
pool.remove(key);
}
}
Another way is to use static elements, wether it be:
Static fields (with public access for example)
Static properties (meaning private fields with getter and/or setter)
Singletons
Possibly nested classes
While the use of static variables in OOP is debatable, they introduce global state and therefore are a way to accomplish sharing of data inbetween activities too.
1) HashMap of WeakReferences, for example:
public class DataHolder {
Map<String, WeakReference<Object>> data = new HashMap<String, WeakReference<Object>>();
void save(String id, Object object) {
data.put(id, new WeakReference<Object>(object));
}
Object retrieve(String id) {
WeakReference<Object> objectWeakReference = data.get(id);
return objectWeakReference.get();
}
}
Before launching the activity:
DataHolder.getInstance().save(someId, someObject);
From the launched activity:
DataHolder.getInstance().retrieve(someId);
2) Or strange method: store data on server O_o
im trying to remove values from an arrayList im my android app, but they keep re-appearing.
My arrayList is in a separate class,
in my Main Activty I create an instance of that class and remove a value from the array.
I exit the Main Activity and return the value re-appears.
My Question is how can I can some kind of static instance of the array class???
//ArrayClass
public class ArrayClass {
public final static ArrayList<String> words = new ArrayList<String>();
public ArrayClass() {
words.add("WORD");
words.add("WORD");
words.add("WORD");
}
//Main Class
ArrayClass wordc = new ArrayClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
wordc.removeWord(0);
}
Orest is correct you do want a singleton pattern, but remember when you access the class's methods you always need to use the getInstance() method.
For example a method within the Class:
public String getWord(index i) {
.......
}
Should be called statically as follows
ArrayClass.getInstance().getWord(i);
NOT like this
wordc.getWord(i);
This guarantees that there is one and only one instance (thus the singleton)
I might be confused on what you are doing but to access the static Array you don't want to create an instance of the class. Everytime you do that you are running the constructor which, in the example code, populates your static Array each time with 3 values.
I don't see exactly what you are trying to accomplish so maybe you could explain that a little better but I'm guessing this really isn't what you want your constructor doing. I think you want to access the Array itself statically
//Main Class
ArrayClass wordc = new ArrayClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
wordc.removeWord(0); //don't need this
ArrayClass.words.remove(0); // would remove the element at index 0
}
But this still wouldn't solve your problem. You need a method inside your ArrayClass class that adds items to your Array. Doing it in your constructor will add these items each time you create a new instance of your class.
If this doesn't answer your question then maybe you can explain your assignment a little better.
Have you tried the Singleton patter? You will have one static reference of ArrayClass and it's internal state won't be violated by activity lifecycle.
public class ArrayClass {
private static ArrayClass instance;
public static ArrayClass getInstance() {
if(instance == null) instance = new ArrayClass();
return instance;
}
//...rest goes as is.
I'm using Gson to deserialise Json into a model ApplicationModel. I want this Model to be a singleton so I can access it elsewhere in my application.
Now as Gson creates an instance of this class, I'm creating the singleton instance in a rather unconventional way. See below:
public class ApplicationModel {
private static ApplicationModel instance;
private GeneralVO general;
protected ApplicationModel() {
instance = this;
}
public static ApplicationModel getInstance() {
return instance;
}
public String getVersionDate() {
return general.getVersionDate();
}
}
This is the way I create it and then reuse it later in the application:
InputStreamReader reader = new InputStreamReader(is);
ApplicationModel model1 = new Gson().fromJson(reader,ApplicationModel.class);
Log.i("MYTAG", "InputStream1 = "+model1.toString());
Log.i("MYTAG", "Date: "+model1.getVersionDate());
ApplicationModel model2 = ApplicationModel.getInstance();
Log.i("MYTAG", "InputStream1 = "+model2.toString());
Log.i("MYTAG", "Date: "+model2.getVersionDate());
This works as the getInstance() returns the same model but somehow this just doesn't seem right.
My question is 'is this a good way of going about it or is there a better solution???'
EDIT
A much better way of doing singletons is to use an enum with one INSTANCE element.
See this post for an explanation
I suggest to instantiate your singleton instance on your Model, rather than instantiating it using constructor.
public class ApplicationModel {
private static ApplicationModel instance; //= new ApplicationModel();
//instantiating here is called an "Eagerly Instantiated"
private GeneralVO general;
private ApplicationModel() {
}
public static ApplicationModel getInstance() {
//instantiating here is called "Lazily Instantiated", using :
//if (instance==null) { --> Check whether 'instance' is instantiated, or null
// instance = new ApplicationModel(); --> Instantiate if null
//}
return instance; //return the single static instance
}
public String getVersionDate() {
return general.getVersionDate();
}
}
By setting the constructor to private, you prevent the object from being re-instantiated by another class, to use the object, you will have to call the object with ApplicationModel.getInstance().
So if you want to set values, call ApplicationModel.getInstance().setterMethod(value), Why this is useful? if you want to track the change, you will only need to track the setter method. If you used constructors, you will have to track the constructors too.
Example :
// To SET the value:
// instead of ApplicationModel model1 = new Gson().fromJson(reader,ApplicationModel.class);
ApplicationModel.getInstance.setValue(new Gson().fromJson(reader,ApplicationModel.class);
// To GET the value :
ApplicationModel.getInstance.getValue();
The "Eager Instantiation" vs "Lazy Instantiation" :
Eager Instantiation is useful if you want an easy way to deal with
Threads
Lazy Instantiation has better memory footprints
There's more than that, you can google it for more info, but I think this should be enough for you right now.
Hope this helps, and good luck ^^
Regards,
Reid
So i have made a class DrawView which extends View and i want to draw some graph in that class with the points i stored as int array
i made this array like a sort of public variable with the help of How to declare global variables
So when i want to get connected with MyApp in Activity and change my array, i simply use
MyApp appState = ((MyApp)getApplicationContext());
but the problem is that this won't work when i call it in my DrawView.java class.
Any ides how to solve this?
I really don't know why that answer is so up voted as it's not a good solution.
The Application object is to run the Application, not to store data, you can solve this MUCH easier with a simple Singleton object, try this:
public Class MyData{
private int[] data;
private static MyData me;
public int[] getData(){
return data;
}
private MyData(){} // private constructor
public MyData get() {}
if(me==null) me = new MyData();
return me;
}
}
than from any object you can call:
int[] data = MyData.get().getData()
and feel free to expand to more than just a int[] ... put any other object that you want to be globally accessible. But remember, DO NOT KEEP REFERENCES TO THE CONTEXT!
I'm trying to create an ArrayList of Data containing Objects (Like a list of Addresses and properties (pretty complex)) and am wondering: How can I make an Object accessible (and editable) by all Activities and not just the one it was instanciated in?
Basically this:
Create Array in Activity 1
Access same Array in Activity 2 and 3
???
Profit.
The easiest way to do this is by creating an Singleton. It's a kind of object that only can be created once, and if you try to access it again it will return the existing instance of the object.
Inside this you can hold your array.
public class Singleton {
private static final Singleton instance = new Singleton();
// Private constructor prevents instantiation from other classes
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
Read more about singleton:
http://en.wikipedia.org/wiki/Singleton_pattern
You can extend the application class. And add your arrays there.
You can access the instance of the class by using this command
MyApplication appContext = (MyApplication)getApplicationContext();
Well you can create a Constant class and declare you ArrayList as a static variable.
1.)
Class ConstantCodes{
public static ArrayList<MyClass> list = new ArrayList<MyClass>;
}
This will be accessible from everywhere you want by just ConstantCodes.list
2.) You can extend your class by Application class like this
class Globalclass extends Application {
private String myState;
public String getState(){
return myState;
}
public void setState(String s){
myState = s;
}
}
class TempActivity extends Activity {
#Override
public void onCreate(Bundle b){
...
Globalclass appState = ((Globalclass)getApplicationContext());
String state = appState.getState();
...
}
}
you should make it static and access it from any other activity.....
how about use a static keyword ?
public static SomeClass someObject
in your activity class that initiate your object
1- In your Activity1, déclare your array in public static
public static ArrayList<HashMap<String, String>> myArray = new ArrayList<HashMap<String, String>>();
2- In your Activity2, Activity3, etc. access to your ArrayList
Activity1.myArray
You can create a java file x beside other java files.
x file contains static method which used to access the class method without instantiate it.
Now make a method called createVariable() and declare variable which you want to make it Global.
Now make a method called getVariable() which returns the Global variable.
At which point you want to create global variable, call className.createVariable().
And to get access to that variable call className.getVariable().
Here is my example for Database class.
public class GlobalDatabaseHelper{
static DatabaseHelper mydb;
public static DatabaseHelper createDatabase(Context context)
{
mydb = new DatabaseHelper(context);
return mydb;
}
public static DatabaseHelper returnDatabase()
{
return mydb;
}
}