Passing complex object to an Activity - android

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());

Related

Can we usually skip using intents by using public variables in Android?

Many times we use intents to send data to a Fragment or get data back from a child. Can't we just put data in a public variable?
For example imagine if we want to get data from user from a dialog box.
I'm just talking about the "possibility". Undoubtedly, It is superior to use intents for code cleanness or safety...
you don't send intent's to fragments, if you want to use objects you need to have your object implement Parcelable then you can just send the object in the intent bundle
public class MyActivity extends Activity {
public int someValue = 1;
}
And in any fragment which has MyActivity as a host you can access ((MyActivity) getActivity()).someValue.
I think what he means is sending (local)broadcast... which is by the way the proper way of doing it according to my understanding.
Of course it is possible to have public (or even protected) fields and access them from a child-fragment with something like this:
assuming your parent activity is named "MainActivity"
((MainActivity) getActivity()).mMyPublicField
or:
((MainActivity) getActivity()).getPublicMethod()
- but I would never recommend doing this!
especially when you also start manipulating the public field you can run into ugly trouble when different threads are in play.
If something needs so be shared across the whole application, use SharedPreferences (if you want to store it for the next app session too) or as I mentioned first LocalBroadCastManager.

Android - Passing objects between activities

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.

Android Singleton Method

So I'm trying to make an application using the Singleton Method. I want to have a class that stores all the information about my device's bluetooth state/connections/devices, and I want to make multiple activites that can access these methods.
I know that I need to have a class that extends Application, then I can access everything by calling getApplication(). What I do not understand, is where I initialize this object. From my frame of reference, I have all of these separate Activities, and if I initialize the object in one, I'm going to need to use intents to pass the object to the next activity, which completely defeats the purpose of using the singleton method.
Any help would be appreciated, thanks.
Simply extend from android.app.Application. Then register it as the application class in your AndroidManifest.xml:
<application android:name="mypackage.MyApplication" ...>
In your class you will receive usual Android calls, such as in
#Override
public void onCreate() { }
where you will able to initialize your global instances.
In the activities fetch the instance of MyApplication downcasting with:
MyApplication app = (MyApplication) getApplication();
Hope that helps.
If you extended Application your class will be created as your app launches. It can be retrieved in Activity classes using getApplication()
Check here : http://www.kodejava.org/examples/12.html
and here : http://www.devahead.com/blog/2011/06/extending-the-android-application-class-and-dealing-with-singleton/
and here : http://inchoo.net/mobile-development/android-development/android-global-variables/

is it possible to access one class file to access its methods or variable by a service and another by an activity AT THE SAME TIME?

I have a class named PatientDetails in which i am storing the values from the xml and then need to access its variables and method from the service as well from the activity at the same point of time ??
This is a typical multi thread scenario. You can do it without any troubles as long as you are just reading the data.
If you are reading the data from patient details class through your activity and writing data to it through your service you will get into run time exceptions. You have carefully synchronize the variables or methods in such cases.
One way to share a 'helper' class is to hold a 'static' reference to a single instance of it in the Application component of your app. Example...
public class MyApp extends Application {
public static detailsHelper;
#Override
public void onCreate() {
detailsHelper = new PatientDetails();
}
}
When you need to use the 'helper' in any other component such as an Activity or Service you simply reference it by the Application name as follows...
MyApp.detailsHelper.doSomething();
Technically speaking, under default conditions there is no such occurrence of two components accessing something at the same time because an Android Application and all of its components exist within a single process with a single thread of execution.
You should be very careful, however, if any of the components execute code which uses threads. For example, an Activity using an AsyncTask or perhaps using an IntentService which creates its own worker thread to do work. In this case, make sure any methods in the 'helper' class which write data, do so in a thread-safe manner.

Android: is it possible to refer to an Activity from a 2nd Activity?

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

Categories

Resources