How do you pass an object between views in an android application. I have googled and found that your class needs to implement the appropriate interface. How though do we do it if we do not own the class/object type we are passing (for example from an external library or a random class within the sdk)
I need to pass a HtmlSelect item object (from HtmlUnit open source project) to another class to process it but I cant bundle it up.
Thanks
My best guess is you create a static helper object and pass it like that.
HelperObject class {
static HtmlSelect myHtmlObject
}
source activity:
HelperObject.myHtmlObject = currentHtlmlObject;
startActivity(intent);
Destination activity:
onCreate() {
HtmlSelect htmlSelect = "create a copy copy of HelperObject.myHtmlObject not to have problems and then set it to null"
}
Just use the putExtra() method of your Intent to pass parameters.
At times you need to first "deconstruct" your object into simple elements (Strings, Integers) and then reconstitute it at the other end with getExtras().
Related
I want to know when to use parcelable and when not to . I know that parcelable is way of parcel complex data type in android , but as per official document http://developer.android.com/guide/faq/framework.html#3 , nothing such is mention . So when is parcelable really needed ??
By implementing the Parcelable interface, you can make your class object capable of being stored in a Bundle and you can then easily pass it to another activity with the help of an Intent.
e.g.
Intent i = new Intent(....);
i.putParcelableExtra("name", object);
Then in the other activity, get it like this:
YourClass object = (YourClass) getIntent().getExtras().getParcelableExtra("name");
Notice the typecasting. That is necessary in order to use your class's methods.
To pass data to another activity, we are usually put bundle object on activity intent that will be called. Bundle can be filled with primitive data types like long, integer, and boolean. It can be filled with simple data type like String class to represent text. For example, an activity calls another activity at the same time sends simple data to it.
In destination activity, we check the bundle. If it is exist, we open the data of bundle from the origin activity.
Now, how if we want to pass the complex data type like our defined class object to another activity? For this need, we can use Parcelable in Android.
Parcelable is an interface for classes so a class that implements Parcelable can be written to and read from a Parcel. The data in Parcel form can be passed between two threads. Parcel itself is a class that have abilities to serialize and deserialize object of class.
i'm developing an app that, when i press a button, downloads a XML file, put the xml data in a custom object and passes it to a second activity.
The problem is that something is wrong: when a call the startActivity() function the app crashes with a Runtime error.
My code is:
public void onClickBtn1(View view)
{
final ProgressDialog dlg = ProgressDialog.show( this, "Data wait", "Waiting data from the site ..");
// Thread to wait data
Thread th = new Thread() {
public void run() {
// Download and parse xml data
final DatiSport dati = new DatiSport();
boolean ret = dati.download();
dlg.dismiss();
// check result
if (ret==true)
{
// -- Ok
handlerUI.post( new Runnable() {
public void run() {
Intent intSec = new Intent(AICSActivity.this, SportActivity.class);
intSec.putExtra("datiSport", dati);
startActivity(intSec);
}
});
}
else
{
The app crashes on the startActivity() call. When i break on the startActivity() line i'm not able to look the variable called 'dati' and i guess this is not well defined.
If i substitute dati with 12345, there is not problem.
Which is the problem with dati ?
--- Changed here cause I'm not enabled to reply myself ---
Ok guys. Thanks for replies!
My guess is that i need to re-design the app data.
My first attempt was: download the XML text and accommodate the data into a (rather) complex object. This object contain a list of championships, each of them contains a list of categories, each of them contains a list of teams.
The problem is that, since the Serializable is not working, the implementation of Parcelable is too complex and it should generate almost the same data as the xml file.
I'm wondering if it should be easier passing directly the xml text to other activities (they have to show in turn the list of championships, then the categories of a selected championship, then the list of teams for a selected category...)
Any other idea?
Extract from this Answer :
Serializable is a standard Java interface. You simply mark a class Serializable by implenting the interface, and Java will automatically serialize it in certain situations.
Parcelable is an Android specific interface where you implement the serialization yourself. It was created to be far more efficient that Serializable, and to get around some problems with the default Java serialization scheme.
Extract from this answer :
Seeing Parcelable might have triggered the question, why is Android
not using the built-in Java serialization mechanism? It turns out that
the Android team came to the conclusion that the serialization in Java
is far too slow to satisfy Android’s interprocess-communication
requirements. So the team built the Parcelable solution. The
Parcelable approach requires that you explicitly serialize the members
of your class, but in the end, you get a much faster serialization of
your objects.
After seeing some answer on StackOverFlow, i come to conclusion that Parcelable is optimized than Serialization in android.
How to make class to Parcelable ?? (Check out this, this & this tutorials)
Use a Serializable or Parcelable when passing objects
You need a class to implement the Serializable class
//to pass :
intent.putExtra("MyClass", obj);
// to retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
Your class would look something like this;
import java.io.Serializable;
#SuppressWarnings("serial") //with this annotation we are going to hide compiler warning
public class MyClass implements Serializable {
public Deneme(Object obj){
this.obj= obj;
}
private Object obj;
}
The Intent class has a method as
putExtra(String name, int value)
thats why it works when you put 12345 at the place of "value", but there is no overloaded version of putExtra that takes "DatiSport" object.
You must ensure that "DatiSport" is Serializable or Parcelable.
See below for more info-
http://developer.android.com/reference/android/content/Intent.html#putExtra%28java.lang.String,%20java.io.Serializable%29
How to send an object from one Android Activity to another using Intents?
How to pass an object from one activity to another on Android
Make your class implement Serializable interface and then pass object instances in intent extra.
To pass data from one Activity to another :
intent.putExtra("ClassName", obj);
To retrieve data in the Second Activity from the First Activity :
getIntent().getSerializableExtra("ClassName");
I found the problem !!!
An internal class were not implementing Serializable!
In the dump window i saw the internal object 'ioe' that said that there was a NotSerializable error and the name of the class!!
Now i checked each internal class and the data is passed to the next activity.
Thanks a lot
Actually,my application flow is like this Home->A->B->Info(form data)->D->Final page.From final page if I press on one button it again navigates back to A page and start the flow from onwards.If I comes to info page I should display the earliear data.Right now my approach is passing parcelable object within all acitivities from A->B->Info->D->Final.If suppose want to use Preferences, doesn't supports the parcelable object and don't want to put each string of object individually within preferences becaus I had more than 10 items within object.Is there any better approach without passing bundle between actvities.
BR,
Developer.
you can create Global class and declare Static variables and use them in anyware in the application.
Example:
public class global_variable {
public static String sample ;
}
where you want to use ;
global_variable.sample = "your value";
You could use any number of technologies to parse your data object into a string and reassemble again. Then you could store the string in preferences.
Take a look at gson to convert objects to json http://code.google.com/p/google-gson/
Or you could google xstream to convert to xml
If you create a class representing your 'object' with appropriate setters/getters and let that class implement Parceable and then pass that class between Activites as a Parceable in a Bundle, would that be bad?
If that would be bad (e.g. if the amount of object data is very big or they are somehow not Parceable in principle) and you only have one meaningful instance of a class at a time you can make that class a singleton or keep it within your Application object.
Is it possible for Activity(s) to communicate using user defined object?
p.s.
So far as I know, when I want Activity(s) to communicate to each other, I have to use primitive type of objects, such as int, String, boolean,...etc.
We don't use Serializable, Parcelable and static class.
If talkin about extras when caling intents, you can implement Serializable or Parcelable interface in your objects to pass them through.
You can also put that object into own implementation of Application class and access it in Activity or Service class as described in my other answer. But please keep in mind, that sharing state in that manner may be a sign of more general problem in your design.
You have a few options:
1.You could wrap the more complex structure in a class that implements the Parcelable interface, which can be stored in an extra.
2.You could wrap the more complex structure in a class that implements the Serializable interface, which can be stored in an extra
3.You use static data members to pass stuff around, since they are all in the same process
4.You use external storage (file, database, SharedPreferences)
5.As the person who just posted noted, use a common component, such as a custom Application or a local Service
What you do not want to do is pass big stuff via extras. For example, if you are creating an application that grabs pictures off the camera, you do not want to pass those in extras -- use a static data member (icky as that sounds). Intents are designed to work cross-process, which means there is some amount of data copying that goes on, which you want to avoid when it is not necessary for big stuff.
Answer copy from here
Intent myintent = new Intent(Info.this, GraphDiag.class).putExtra("<StringName>", value);
startActivity(myintent);
use the above code in parent activity
and in child activity
int s= getIntent().getIntExtra("<StringName>");
in the same u retrive the float,char,String values
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.