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

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.

Related

How do I pass variables between activities in 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.

When to use FLAG_ACTIVITY_RETAIN_IN_RECENTS?

I am trying to familiarize myself with intent flags, and I want to understand FLAG_ACTIVITY_RETAIN_IN_RECENTS. I have read the documentation and it seems like if this flag is set when calling an Activity, if the user presses the back button or that Activity is finished(), it still remains on the stack. Is this interpretation accurate? If not, what is this flag used for?
Reference: http://developer.android.com/reference/android/content/Intent.html
Thank you in advance!
I have read the documentation and it seems like if this flag is set
when calling an Activity, if the user presses the back button or that
Activity is finished(), it still remains on the stack.
No, the Activity will not remain on the stack, but its entry will be shown in the recent task list, you can click on that entry to re-launch this Activity just as you re-launch your application.
Another Usage in OverviewScreen:
If you want to retain a task in the overview screen, even if its activity has finished, pass the FLAG_ACTIVITY_RETAIN_IN_RECENTS flag in the addFlags() method of the Intent that launches the activity.
private Intent newDocumentIntent() {
final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet());
return newDocumentIntent;
}
To achieve the same effect, set the attribute android:autoRemoveFromRecents to false. The default value is true for document activities, and false for regular activities. Using this attribute overrides the FLAG_ACTIVITY_RETAIN_IN_RECENTS flag

How long is a Intent available

Im wondering how long does getIntent() in a Activity will be available (does not return null). So lets say I start Activity B from my Activity A and pass some extra data in the Intent.
In Activity B I will read the extra data from the intent in the activities onCreate() method.
So far so good. But how long is getIntent() available? I mean, if the user is displaying Activity B, but switchs to another App (i.e. by using the multitasking button) and after some hours the user clicks on the multitasking button again (the activity may have been destroyed in the meantime) and opens Activity B again. So Activity B onCreate() will be called to reinstantiate the Activity B. Does getIntent() now still returns the original Intent with the extra value or do I have to save the Intent extra value in Activities onSaveInstanceState() and use the Bundle in onCreate(Bundle state)?
Does getIntent() now still returns the original Intent with the extra value
Technically, it returns a copy of the Intent. Generally speaking, it should be identical to the original Intent, including all extras.
From Android doc, getIntent() return
Return the intent that started this activity.
But their are so many case where getIntent is null or extras are null. Check this link and this. Specially on device rotation or from pressing back keys.
But as its seems documentations says otherwise. Just to be in safe side, i will recommend you to do following
if (getIntent() != null && getIntent().getExtras() != null){
}
And, your activity code should prepared to handle the scenario where getIntent is null.

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 .

How do I avoid onCreate() being called when starting an Activity?

I want to reload an activity from stack.
I use startActivity() to start new activities. When I'm on Activity D I want to reload Activity A and not start a new Intent. I can't use startActivity() when calling A from D because it will fire onCreate() which starts a thread to fetch some data.
EDIT: Updated the stack.
If I use FLAG_ACTIVITY_REORDER_TO_FRONT it calls the onCreate() method again.
Following is my scenario.
Login Activity ̣→ Activity A → Activity B → Activity C → Activity D → Activity A
How do I avoid onCreate() being called?
You have to take a totally different approach. It doesn't matter if you start your Activity with startActivity() or startActivityForResult() because onCreate(), onStart() and onResume() will be called when you start an Activity.
Now if you have a method in your Activity class that starts another thread to do some work then you have to work with flags. If your Activity requires to automatically start the thread on first execution then you have to wrap it around an if clause to check for a flag you set when it is first run.
The idea is to have your Activity set a boolean to true in either your Application instance or SharedPreferences when the thread is first executed. When you come back to that Activity and don't want that thread to be run automatically due to onCreate() being called then you have to wrap your calling code around some if clause like in the example below.
Here is an example.
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
// Other stuff
if (!YourApplicationInstance.wasCalled) {
// Run your thread or do something else you want to do only once.
// Set the wasCalled flag to true to not run this code again
// if onCreate() is called a second time.
YourApplicationInstance.wasCalled = true;
}
}
You'll have to read Using Application context everywhere? to understand how to implement my pseudo class YourApplicationInstance.
The following is not true. startActivityForResult() and startActivity() only differ in the return target of the called Activity
try using startActivityForResult() rather than
startActivity(). I believe this does not completely end the activity and start it again. I
would recommend using this link in order to further read on how to implement such a method.
So point 2 of #Kgrover does not hold too.
The Intent flag http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT does exactly this.
Keep an eye out on the Intent flags whenever you have requirements centered around Activity transitions. The system has excellent support.
This is equivalent to Sam Quest's solution, the only difference being that if you set the launchMode, the stack-behavior of your Activity is hardcoded i.e. your Activity A is always in the singleTask mode.
there is tag called launchMode for activity in the manifest. checkout this link. and this will not call onCreate but it will call onNewIntent, where you can reinitialize you stuff.
1) Although I am not sure, you could try using startActivityForResult() rather than startActivity(). I believe this does not completely end the activity and start it again. I would recommend using this link in order to further read on how to implement such a method.
2) Alternatively, when you go from activity D -> A, continue to use startActivity(), but pass in a dummy extra. Then in activity A, use an if statement:
if(!(this.getIntent().hasExtra("dummyStringExtra")) {
//fire the data thread here
}
Cheers. I hope this helps.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
This will kill the child activity. So parent activity is not recreated

Categories

Resources