How do I pass variables between activities in Android? - android

Assume I have a "post submission" feature on my application. There are two activities and layouts:
Main post activity
Location selection activity
How can I pass variables between them when they're already opened? I already know how when they haven't been opened. I use "singleTask" mode to prevent multiple instances.
Reason I need this is because there's a button that links to LocationSelectionActivity on the MainPostActivity. I want when someone clicked the button, select the location, then go back to the MainPostActivity without any activity restart so the filled fields will not reset.

Use onActivityResult() with startActivityForResult().
Reference: https://developer.android.com/training/basics/intents/result

You're probably looking for onNewIntent, you can override it in your Activity class and retrieve the new Intent in your onResume method.
/**
* Override super.onNewIntent() so that calls to getIntent() will return the
* latest intent that was used to start this Activity rather than the first
* intent.
*/
#Override
public void onNewIntent(Intent intent){
super.onNewIntent(intent); // Propagate.
setIntent(intent); // Passing the new intent to setIntent() means this new intent will be the one returned whenever getIntent() is called.
}

You should not use Activities for this, you are in your own "main process" so you should be using 1 Activity and 2 Fragments for this.
Then you can use locationSelectionFragment.setTargetFragment(this); in MainPostFragment before it is added to Activity's fragment transaction, this lets you use getTargetFragment() to just pass back the value:
((MainPostFragment)getTargetFragment()).giveValueBack(value);
But there are multiple other options each with their own strengths and weaknesses as described in this article.

Related

What is the usage of the method Activity.startNextMatchingActivity(Intent)?

The API says "You can use this to hand the Intent off to the next Activity that can handle it. ".But we can use startActivity(getIntent()) to do that too.What are the diffirences?
Take a look at what the doc says:
startNextMatchingActivity
Special version of starting an activity, for use when you are
replacing other activity components. You can use this to hand the
Intent off to the next Activity that can handle it. You typically call
this in onCreate(Bundle) with the Intent returned by getIntent().
Parameters
intent The intent to dispatch to the next activity. For correct behavior, this must be the same as the Intent that started your own activity; the only changes you can make are to the extras inside of it.
options Additional options for how the Activity should be started. See Context.startActivity(Intent, Bundle) for more details.
Returns
Returns a boolean indicating whether there was another Activity to
start: true if there was a next activity to start, false if there
wasn't. In general, if true is returned you will then want to call
finish() on yourself.

How to identify which Activity was 'opened' in onResume

In my main activity I want to override the onResume method so it acts differently, depending on the activity, which was opened before.
For example: if the user creates a new Item for the listView (in the addNewItem activity), I need to reload the database to display the newItem.
But if he just switches into an activity, which doesn't change anything with the objects displayed in the main activity, the database shouldn't be reloaded and the GUI shouldn't be build again.
Therefor I need to know which activity was 'opened' before.
I hope you understand my problem.
A dirty way is to extend your application class and set an attribute lastActivity that you would set in every onResume/OnPause methods of every activities in your app. This way, when your main activity on resume is called, just read this lastActivity field to know where you come from. But I think it's the dirty way to do it :D
You can send something through in your intent when you call the Activity.
Intent myIntent = new Intent(Activity1.this,Activity2.class);
Bundle myData = new Bundle();
myData.putString("previousActivity", "Activity1");
myIntent.putExtras(myData);
startActivity(myIntent);
Then in the new Activity, you access this and compare the result:
Intent myLocalIntent = getIntent();
Bundle myBundle = myLocalIntent.getExtras();
String str1 = myBundle.getString("previousActivity");
if string.equals("Activity1"){
// do code changes for activity 1 here
}
There are slightly more refined ways of doing this (i.e passing through an int variable which corresponds to a particular Activity) but this is the most basic way.
The right way to do it, is to start every activity with startActivityForResult(intent, resultCode).
When an activity exits, it can call setResult(int) to return data back to its parent.
Link to Developers Resource

Activity struck while pressing back key

There is no action performed on the activity when i press back key till some time. No code return to handle back key in my activity. I am starting a activity when user clicks on list item. Like
Intent intent = new Intent(cxt, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Actual thing hapening is,when user clicks instantly thrice,My activity is launched multiple times.How can i avoid launch activity more than once.
I can not use single instance/singleton because my OnCreate should be called every time the activity is launched.
I would assume that you do extensive processing in one of the Activity lifecycle callbacks which Android calls in this case to destroy your Activity.
Decide wether you start an activity or not outside the activity itself, and consider checking conditions there. You can pass parameters to your new intent based on the conditions.
here is a question on that topic: How to start an Intent by passing some parameters to it?
you can still use singleInstance and override onNewIntent method which will be called on every relaunch of activity , or separate expensive operations in handler post methods .

One instance of an activity being started with an intent

I have an activity that is started from another activity via a button and which gets passed an intent when started.
I now figured out, that the activity is then created several times, since it is started with an intent, and will call onCreate() every time I hit the button mentioned above. In the documentation I read it says "Every time there's a new intent for a "standard" activity, a new instance of the class is created to respond to that intent", so that I assume that I then have several instances of that activity somewhere on the stack. This is what I would like to avoid, since the activity has some static variables which are referenced from other activites and I want to make sure that the value of this variable is deterministic!
What I want is to get rid of all existing instances and create a new instance of the activity when I press the button, or make sure to have just one activity and create it with the new intent everytime.
I tried to achieve this by setting android:launchMode="singleTop" for the activity and implementing onNewIntent(intent). This should make sure that I only have one instance of the activity in this scenario and I get the new intent. However if I do it like this, I basically have to copy my whole onCreate() method, but just using the new intent, which feels wrong.
public void onNewIntent(Intent intent) {
myAdapter= null;
serverThread.stopThread();
serverThread = null;
this.onCreate(...); // <- somehow do all this with new intent
}
Do you have a good idea how to solve this situation easily?
You can move all that code from onCreate() to onStart() to make sure it's called every time that activity is being opened
Try setting the flag FLAG_ACTIVITY_REORDER_TO_FRONT
It will ensure that if an activity exists in the stack, it will bring that activity to the front.
Intent intent = new Intent(getApplicationContext(),
YourCustomActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
In the above situation actually onDestroy() is called when the user is navigating back to the previous activity with the button creating the intent and starting the activity. I.e. actually in this case there is already only one instance of the activity and the previous one is being destroyed.
For this reason onNewIntent() is not called in the above setup. If you want to e.g. stop a server, as indicated above in the question by a piece of code, so that you can start a new one when pressing the button again, you hence can actually simply do this:
#Override
public void onDestroy() {
serverThread.stopThread();
super.onDestroy();
}
Hope that helps others :)

Start new activity from notification in android

I want to start a Activity A from status bar notification, When the activity A is already in front then i want to finish that and fresh start activity A. How can i do this?
Review the documentation on creating Status Bar Notifications. This definitely covers starting and Activity from a Notification using an Intent and PendingIntent.
http://developer.android.com/guide/topics/ui/notifiers/notifications.html
As for if the Activity is already running, finish it and start it freshly... I'm not sure that can be done easily, depending on what you really want. You may be able to do something with the launch mode activity parameter in the manifest:
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
And then have your activity respond (with onNewIntent() most likely) and "reset" itself programmatically. Possibly with something like this:
Android restart my activity
You mean re-start Activity A? While the most common approach is just to re-launch a new Intent with your same class I think it uses way too memory. I'd rather create an "init" method which should be called from the onCreate AND when you want to re-launch your activity. Example:
public void onCreate(Bundle si){
// Call super and set your layout...
init();
}
/**
* This method should be called whenever you want to restart your activity. The
* biggest advantage is you already have your layout (setContentView() method)
*/
private void relaunchActivityA(){
// Clean or save anything you need to clean or save
init();
}
private void init(){
// Init your variables, threads, and so on
}
If you wrote 'finish that and fresh start Activity A' instead of 'Activity B', then right after your startActivity() -on activity A- call 'finish'. Example:
// This is inside Activity A
Intent i = new Intent(this, ActivityB.class);
startActivity();
finish(); // This will be called right after 'Activity B' finishes

Categories

Resources