Pass parameter by reference using intent - android

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

Related

How to correctly create and use Android global variables?

I have an application whose different activities need an access to many values that could be stored in a global variable in order to know which views should be visible and/or enabled. It is a kind of views-visibility variable. The thing is that I want to save all those visibility values in the different attributes of this object and I want this object to stay safety alive for all the application lifecycle, then is when I came down to global variables.
I've read different options to do this:
1) Creating this object in the main activity using Singleton pattern.
2) Creating this object as an static class and fulfilling the values in main activity.
3) Creating this object as a calss extending Application in the main activity.
Then the object is supposed to be called and accessed from each activity of the application. But, is any of these options correct and efficient to access global variables? Is it recommended to avoid using global variables?
Thank you

iOS controllers data sharing vs Android activities data sharing

I'm developing a native app for iOS and Android and i noticed something different that intrigued me. This is not an issue or a bug, maybe only a different behaviour on different platforms, but i'd like to understand why and if i'm missing something.
Let's suppose there are 2 Android activities:
Activity1 starts Activity2 and using intents bundle assign its model to Activity2 model
The same for iOS controllers:
Controller1 starts Controller2 and using segues assign its model to Controller2 model
When i modify the model in Activity2 and go back to activity1, the model is not updated so i have to notify this change (using broadcast, delegates or other..). The same is not for iOS because when i go back to Controller1 the model is already updated.
Why this happen? Are iOS controllers working on the same model instance while Android activities make a clone?
On iOS you pass the object by reference to the new VC. So if you change a property of that object in the second VC, that change is visible to the first VC because it is the same object.
On Android when you pass objects via a Bundle they are serialized and deserialized which can create a new object, thus the change is not visible in the original Activity. When passing Parcelable data between fragments they can be passed by reference and the change is visible in the original Fragment.
EDIT:
In Java/Android objects are passed by value, not by reference, thus when you assign a new object into a variable the old one is not changed in the original fragment. But if you change its internal state (e.g. property/field), then this is reflected in the original fragment.
Check your IOS code, you will find one method with name "viewWillAppear" on first controller, so this method will update changes which you have made on previous screen.
Same thing you can apply in Android by using method "onResume()", so implement this method and write your update task from "onCreate()" method to "onResume()" method.
In both IOS and Android, the main method "ViewDidLoad()" and "onCreate()" calls only once when activity or controller starts, then they will notify by "viewWillAppear" and "onResume" method.
Check this will help you.
The difference you notice is due to the two differents programming language used.
In Android you are using Java, and in Java nothing is passed by reference, everything is passed by value. Object references are passed by value.
Additionally Strings are immutable in Java, so if you are passing a String to Activity2 using intents bundle, and you modify it in Activity 2, the system allocate a new String in a different memory address.
See this answer about Java parameter passing.
Hope this helps

Android Base Activity: Base's Global Variables, Can't get from some activites

I'm taking an android class now, so I am somewhat new to android app development.
My first assumption for a Base Activity is that it's Global Variables and it's values would be available to all activities. I have found that it is available to my Main Activity, but not any activities after that.
In the Base Activity I am storing an ArrayList of Objects. I also load data from an xml in there that adds objects to the arrayList. Once in the Main Activity I still have access to that arrayList and it's values. I use it to fill a list. But when I go to the next activity, it knows about the arrayList but thinks it is empty.
Do I need to create methods in the base activity to retrieve the arrayList and to add objects to the array list?
Any help would be appreciated.
Thank you,
Michelle
Global variables need to be declared static. Then they would be accessible from any class. Example:
public class Globals {
public static String myString;
}
Any class can read/write the myString like this:
Globals.myString = "foo";
or
String bar = Globals.myString;
From experience I believe the variables of one activity is only avaliable to the other while the activity is active, which means between onCreate and onDestroy, other then that you will probably get a null pointer exception, what you really should be doing is sending the data, or arrays, along with the intent to the other activity.
I dont think you should be calling on other activities variables, although it is possible as stated above. I believe when the activity has had it's onDestroy method called the objects in the activity are destroyed to and are removed from memory. Destroying anything that they held.
What is this base activity? Does it just extend activity? And then MainActivity is extending Activity as well? Only one activity is usable at any one time, if your doing what I think your doing you should have a service which can provide you with everything over the cycle of the application, just remember to stop it when your done with it.

Android: Access method in an activity from another activity

My launch activity starts up another activity whose launch is set to single instance. In this 2nd activity, I have a public method. I then start up a 3rd activity and that activity needs to access the public method in the 2nd activity. I don't want to use startActivity and pass it extras because I assume the onCreate will get called (or am I wrong?) and I need to avoid the 2nd activity from reinitializing itself.
When an activity is started using startActivity, is it possible to gain access to the underlying class instance itself and simply call the method?
I actually came up with a simple solution. As a matter of fact you can access the underlying class of an activity. First, you create a class that is used to hold a public static reference to activity 2. When activity 2 is created, in its onCreate method you store "this" in the static reference. Activity 2 implements an interface with the methods that you want available to any other activity or object. The static reference you hold would be of a data type of this interface. When another activity wants to call a method in this activity, it simply accesses the public static reference and calls the method. This is no hack but is intrinsic to how Java operates and is totally legitimate.
It is not a good idea.
As I can understand method from second activity is actually not connected to particular activity while you want to call it from another one. So carry the method out to other (non-activity) class (maybe static method) and use it from both activities.
It's not directly possible to gain access to activity object started using startActivity (without using some hacks). And frankly you shouldn't even trying to accomplish this.
One Activity component can cycle through several Activity java object while its alive. For example, when user rotates the screen, old object is discarded and new activity object is created. But this is still one Activity component.
From my experience, when you need to do things you described, there is something wrong with your architecture. You either should move part of activity's responsibilities to Service or to ContentProvider, or use Intents, etc. Its hard to recommend anything more specific without knowing more details.
No there is no way to pass a reference via startActivity() however you can use some sort of shared memory to keep reference to your Activity. This is probably a bad design. However passing an extra with your Intent will not cause onCreate, that is completely related to the lifecycle.

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