I use the putExtra and getSerializable Methods to pass my object to a second activity. It works fine, however, am I required to return this object in order to maintain the changes made in the second activity?
When I run my app, and launch my second activity then call finish() after makimg a change to the object passed to it, if I relaunch that second activity the old object data previous to the change is displayed, does this mean that using the put/get serializable methods are passing a clone of the object, and that in order to keep the changes made on the second activity I must repass the object back to the main activity ?!
I am not sure why would you require such behaviour.However you can try the following methods.
You can make that object as global static variable(preferably in the application class of the app) so that the object is retained between different instances of the activities.
Also if the state of the object is important across app restarts you must plan to write the state of the object in some persistent storage like db/file/shared preference.Refer this link for storing object,
Related
While working with different activities and starting them for results I have no choice but to use intent. Now intent requires context and that makes no sense to me. I know that context allows access to the application resources but
why do you need to know about the application resources when an intent is just a simple messenger?
Also, I am not so sure why some people create intent with the getApplicationContext() while other use this for the activity context????
Lastly, I am not so sure how the activity that calls for startActivityResult() receive a call back on the method onActivityResult() when I don't pass the "this" for the context but instead the application context. I thought that you have to use the "this" or passing in the current activity context that called startActivityResult() in order to receive a callback. That is just straight up java right? If you pass in a class then the other activity class will have a reference to your class and hence allows it to call the method in your class which is onActivityForResult(). However, this is not the case so what am I missing?
Intent itself does not need the Context. The constructor Intent#Intent(Context, Class) is just a convenience constructor, that internally uses the provided arguments to derive a ComponentName. ComponentName is in turn just a package name of your app and a class name to target. So ComponentName might be something like:
com.foo.bar/com.foo.bar.ui.activity.MyActivity
However, you can as well just use an empty constructor Intent#Intent() and provide ComponentName yourself (Intent#setComponentName(ComponentName)).
Therefore it doesn't matter if you provide your Application's or your Activity's context (the latter is just simpler to type). Also keep in mind that classes that require application context can call Context#getApplicationContext themselves, so this is not something you need to worry about.
About startActivityForResult() - Android manages internally a stack of your Activity records. Therefore it delivers the result to the previous Activity on the stack. It is the same way it knows where to return, when you click "back".
Please note it doesn't mean it maintains a stack of your Activity instances. These instances might be long gone - destroyed and garbage collected to free the memory. However the stack contains the information that allows to recreate them and to restore their state.
Intent does not need Context for itself but as you yourself pointed out that Intent is just a messenger. It also passes the current state of application/object to the newly created object so that it can understand that what exactly is going on in the application. And that is why we need to pass the context.
And, I believe that you want to ask about startActivityForResult(). Android itself takes care of the callback in the same way other callbacks are handled. You can take the example of Activity Life-cycle. Whenever it is started onCreate(), onStart(), onResume() are called itself by Android.
Not been much deep into Android development but still let me try with an explanation. So basically, context is a reference to linking your resources to your program. Each object is given its own context, which contains the resources required to set that object up. It is required for many objects to be created, and to get program identifying information, among other purposes. This makes it invaluable to set up new views and activities, but it can also be used for other purposes. See this Android Context for more information.
According to this page Activity inherits context. Thus, if you are in an activity, you only need to pass itself to use the context. It also contains a pointer to getBaseContext(). You might occasionally need to reference that, if you need the entire application context, but most likely you won't for a while.
There are ways of creating an Intent which do not require a Context. But if you want to target a specific class of a specific package, then providing a context for the target package is a ready way to do that. Refer this Context Lesson.
As explained by snctin in his answer getApplicationContext() offers application context. Basically the Application context is associated with the Application and will always be the same throughout the life cycle of your app. Also refer this post.
See Android - How to start (display) a new Activity. According to it
startActivity(new Intent(this, ProjectsActivity.class));
assumes your current class extends one of the Android Activity classes, which gives you access to the startActivity method.
According to Getting result from a activity, Starting another activity doesn't have to be one-way. You can also start another activity and receive a result back. To receive a result, call startActivityForResult() (instead of startActivity()).
For example, your app can start a camera app and receive the captured photo as a result. Or, you might start the People app in order for the user to select a contact and you'll receive the contact details as a result. This post will help you understand the same more better way.
Hope that helps. And also thanks becuase of your question I had a refresh with Android.:)
I'm calling ActivityCompat.requestPermissions in order to get permissions under android M, however, this requires an activity in the argument. This would be fine, except that I want to call it from a singleton, and the singleton can be used by any activity in the app.
ActivityCompat.requestPermissions(context, PERMISSIONS_LOCATION, REQUEST_LOCATION);
I want to avoid holding a reference to any activity within the singleton as that's a surefire recipe for a memory leak, and also I'd prefer that the singleton not hold an activity at all because it requires useless code in all the activities that call (every single one of them is going to have to include an extra argument in the getInstance() in order for the singleton to hold an activity - the singleton needs to get the activity from somewhere).
Now, I can technically get an activity and then set it to null straight after I request the permission, however that still leaves me with tons of useless activity arguments in every single activity where I make a call to the singleton. Is there a more elegant solution to this problem that I'm just not seeing?
The documentation on requestPermissions says that the activity parameter is the target activity where you want to show the pop up if you haven't included the permission in your manifest and for this purpose that method requires you to pass an activity and not the context, because upon finish the request permissions task it will then return a result to the calling activity(that is the activity passed as the parameter to the method). If you are so adamant about implementing this through your singleton I suggest you create a function that accepts the activity in the parameter and the callbacks too as you WILL need to handle the callbacks if the permissions were given or not
The question is simple, if I make an object parcelable, and put it into a bundle and create a fragment using the bundle. Does the object get cloned or is it referenced.
The context.
I have got an object stored/referenced in an ArrayList. Depending on the type of object in the ArrayList (polymorphism is used). I create a fragment suitable for dealing with it.
I need to also pass this object to the fragment. The fragment is used within a custom view pager. I do not wish to have duplicate objects and it seems to me parcelable clones objects.
Another method is to pass the index of the object in the ArrayList. and then get a reference to the arraylist from the fragment using getActivity().myList.get(Integer passed to ). But it doesn't seem very safe to me (ArrayList contents may change, although I simply delete everything and start again). I have also read, that you should avoid passing arguments to a fragments constructor as it may be recreated using the default no-args constructor.
(Although I'm currently destroying any recreated fragments as there are some strange problem with reattaching to the correct view, another post).
New sub-question: is there a way to pass a value by reference to a fragment?
The question is simple, if I make an object parcelable, and put it into a bundle and create a fragment using the bundle. Does the object get cloned or is it referenced.
It may get cloned, if not immediately, at other points in time (e.g., when the fragment's arguments Bundle is included in the instance state).
I have also read, that you should avoid passing arguments to a fragments constructor as it may be recreated using the default no-args constructor.
Correct.
Another method is to pass the index of the object in the ArrayList. and then get a reference to the arraylist from the fragment using getActivity().myList.get(Integer passed to ). But it doesnt seem very safe to me (ArrayList contents may change, although I simply delete everything and start again).
Don't use an ArrayList. Use a HashMap with a durable key. Pass the key to the fragment. Have the fragment get the data via the key. Make sure anyone deleting this object (and thereby removing it from the HashMap) does so only when this fragment does not exist, or notifies this fragment so it knows how to handle this scenario.
I have an Activity A, Activity B and an Object C. I need to start Activity B from Activity A and while starting i need object C to find user location and once it is available Activity B must be notified with the location object.
I am not sure how Object C can notify Activity B since android dosent allow to get hold of Activity References.
Look into implementing a Bound Service. Your location info could be fetched within this service (on another thread, of course), and retrieved within Activity B when it binds to the service.
Create an AsyncTask that will find the user location in the background.
Once completed, you can update the UI or maybe create a notification to the user.
Use Java Observer and Observable classes.
By extending the Observable class on your data object (model), you are able to assign Observers which listen for changes in said data model. When the data changes, the Observer is notified automatically and fires its update() method.
The update() method is an obvious place to put your code which refreshes the views impacted by the changes in data, this is where the linkage between the views and the data model occurs (usually in the Android Activity). The beauty of using the Observer and Observable classes is that the data model, views and controller (the Activity that updates the views) are all separated. That is, you can use the data model for whatever you want, if you change the views it won’t break the data model and vice versa. This makes your app much simpler to understand and easier to update later down the road.
Here's simple code example: http://www.ootpapps.com/eclipse_projects/ObserverExample.zip
In my main Activity I have object with some data in it. I want to delete all this data through PreferenceActivity using method (wipe()) that does this job. How can I do it?
Inside Preferences.java there is a OnPreferenceClickListener which, when activated, expected to use method in object that I need to access.
Thanks in advance.
Just make this object as static.
Then you can access to this object by class name.
Activity.counters.wipe();
But, keeping data in activities is a bad practice in android development