I know that if I want to send a custom object O from Activity A to Activity B, I have to make the object O implement Parcelable.
However, currently my object O has a lot of various types of fields.
In this case, can I just use a singleton?
For example,
1. in Activity B, I create a public static Object o;
2. in Activity A, I do
B.o = ObjectToSend;
startActivity(intent for B);
3. in Activity B's onCreate(), I do
O o = B.o;
if o is not null, use o..
Is there a problem with this approach?
Thanks
can you just make it serializable? ( if so, look into this question for an example: Pass serializable object throught intent )
if you really want to go with the "static" approach, i'd look into using a subclass of Application, it's more designed to handle application state, which is what your are trying to pass around. if so, google "android custom application class" and you will get some pretty good blogs and posts about using it.
a decent note on Parcelable vs Serializable
Assuming no other threads could change those variables it will work that way, but it's usually more common to separate the Singleton out into it's own class (e.g.)
public class ObjectSingleton{
private static ... someobject;
//getters and setters
}
So it's easier to wrap thread safe code around it.
You can subclass your own Application class and make your object a field of that class. Your Application subclass exists as long as your program is running so your object will be there all the time.
Related
I need to pass an object between 2 activities that have no connection between them (meaning, neither of them calls the other).
My Main_activity extends TabActivity. I have 2 tabs : CurrencyList (extends ListActivity implements OnItemSelectedListener) and CurrencyCalculator extends Activity.
I also have class currencyData that saves data about different currencies.
In the CurrencyList activity I created a new currencyData object and initiate it with data.
How can I pass it also to the CurrencyCalculator activity?
2 quick ways:
1. use an static method in your activity to retrieve current ticket id
2. Design and implement an interface and register the fragments as listeners from the activity
Static Method is preferable for large data.
If there is absolutely no connection between them, then one method of accessing data in different Activity classes would be to declare the data members as static class members. Keep in mind that static objects from Activities persist even after you destroy the activity and Android keeps this around for some time even after the you leave the application.
These might not be the easiest ways (just some alternate approaches to the two answers given). You can use a Handler or a BroadcastReceiver to pass the data to the other activity through an intent.
Note
that your object would have to implement either Serializable or
Parcelable if you want to pass it through an intent. I have used
Serializable before and as long as your object does not have any
nested custom objects, you actually have to do no additional work.
Also the assumption is that the receiving activity is alive and is
able to receive the broadcast and/or message.
Another approach would be to write the object to a file (again it would need to be serializable) and read it back in the other activity.
Using itent.putExtra makes a copy of my object. So changes make on this object on the activity that recive this itent does no reflect on others activity.
In my case will be good have reference to this object instead a copy, this is possible ?
ps: I know i can use onActivityResult to retrive the changes make on the object, but in my case the changes make on the object need to be done before the end of the activity.
Other way is: set a reference to a common property from activity1 (I am using MyApplication). The activity2 knows where to find that reference via a getter and it will use it. Decide if you want to modify the properties in activity2, when finished / every time you can have the reference in activity1.
This way is not needed to serialize / deserialize the object either. ( performance improvement too)
You can just store a reference to the object in a static member variable, like this:
public class Globals {
public static MyObject myObject;
}
Now, in the code that has the object, you just do:
Globals.myObject = object;
and in the new activity, you can get it like this:
doSomethingWith(Globals.myObject);
Now, having said that, you need to be aware of the following:
Android can kill your process if your application is in the background pretty much any time it wants to. When the user then returns to your application, Android will create a new process for your application and then it will recreate only the activity that was on the top of the activity stack (ie: the one that was showing). In that case, the newly created activity will not be able to get the iobject by accesing Globals.myObject because the process has been newly created and that member variable is null.
You should use an Application class, which you can get a reference to using the getApplicationContext() method.
Bottom line, create an Application class, which you will be able to reference from any class in your App, then you can reference a variable that is local to that class.
Here is a good SO question about this:
Using the Android Application class to persist data
I need to keep a reference to an object between different activities. The two said mentions seem to create new objects from activity to activity. This is a problem because changes to the object in the "child" activities don't persist once the parent activity gets focus. My solution to this was just to create a static getter in the parent-most activity which the child activities call and work with. Is this the incorrect way to go about this?
If you want to share a single instance of an object between activities, you can create a singleton class. The only thing wrong with using your parent-most activity class to implement the singleton might be that it might violate the single responsibility principle.
You can make your object persistent throughout the whole application lifecycle by making it a field in your Application-derived class.
public class MyAppication extends Application {
private Object mMyData;
public setData(Object data) {
mMyData = data;
}
public Object getData() {
return mMyData;
}
}
Then ((MyApplication)getAppllication()).setData or getData()
This way you can exchange data within the application because MyApplication will always exist.
You'll also have to add MyApplcation to manifest
You should create a Singleton, this has a single instance whenever you talk to it. (Just like your describing).
Here's one I made earlier : https://stackoverflow.com/a/6539080/413127
I'm working with a Bluetooth app, and I have a thread listening to input messages, and 2 activities: main menu, and bluetooth console. I'm making the connection in the menu Activity, and then I need to pass some objects to the console Activity:
a thread reference to use its write() method
the Context from main Activity
and a boolean I need to check eventualy
I read about using Intent.putExtra and passing a serializable o parceable class object. I wrote a class with the objects I need to pass, but I don't know how to do this, or even what serializable and parceable means.
Isn't there any easy method to pass these objects from an Activity to another?
You could extend Application and put the shared objects into that class. Something like:
public class MyApplication extends Application {
private boolean myBoolean;
public boolean getMyBoolean() { return myBoolean; }
}
You can put anything here you want to use a global variables.
To set the Application of your app to MyAPplication, use the AndroidManifest.xml
<application ... android:name=".MyApplication">
In short answer. No. Activities are isolated from each other because they can span processes so the only portable option is to serialize them. But you can use libraries like Flexjson to serialize plain old Java Beans across using Intent.putExtra(). Much simpler than hand writing serialization with Parcels. Check out: http://flexjson.sourceforge.net
There is a bug in Android that you have to do the following:
/** Fix for Android bug http://code.google.com/p/android/issues/detail?id=5697 */
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
This is a pretty simple question, but I have been unable to find anyway to accomplish what I am trying to do...
I want to launch a new Activity to display some complex information. Because of the complexity, it is undesirable to serialize the information into the intent's parameters. Is it possible for the the new Activity to get a reference to the launching activity, so it can call its methods?
If you use a custom application class, you can store information that will be kept between the activities.
See a tutorial here for instance.
The lifetime of an Activity cannot be depended upon. In this case, one way of sharing data is to have a singleton which holds the data to be shared between the two activities.
You can add a public static field to the first activity containing this (the first activity).
But beware that the first activity could be destroyed by Android while you are using the second activity, so you will have to implement a fallback method if the first activity is destroyed.
And don’t forget to unset the public static variable in the onDestroy() callback of the first activity or you will leak memory.
Is it possible for the the new Activity to get a reference to the launching activity, so it can call its methods?
Please do not do that. Android can and will destroy activities to free up memory.
Complex information like you describe should not be owned by an activity. It should be held in a central data model, like you would in any other application. Whether that central data model is mediated by a Service or a singleton or a custom Application object depends a bit on the type of data, caching models, risks of memory leaks, and so on.
You can make your complex objects public and static in ActivityA, and access them in ActivityB like this:
MyCustomObjectType complexFromA = ActivityA.complexObject;
this will work, however while in ActivityB, you can't always be sure that static objects from ActivityA will exist(they may be null) since Android may terminate your application.
so then maybe add some null checking:
if(null == ActivityA.complexObject) {
//go back to ActivityA, or do something else since the object isn't there
}
else {
//business as usual, access the object
MyCustomObjectType complexFromA = ActivityA.complexObject;
}
You could also use a Singleton object which extends Application. You would have the same problem when Android terminates your application. always need to check if the object actually exists. Using the Singleton extending Application approach seems to be the more organized way - but adds more complexity to implementation. just depends what you need to do and whatever works for your implementation.
You should create a separate class that both the activities can use.
public class HelperClass{
public void sharedFunction(){
//implement function here
}
}
I would recommend staying away from static variable in android. It can cause some unexpected behavior.
Use getParent() from new activity and call parent's method
Android Activity call another Activity method