I have this piece of code which basically should launch an activity and act upon it, for example, set its title :
void launchAnActivityAndSetItsTitle() {
context.startActivity(intent);
activityMonitor.getCurrentActivity().getSupportActionBar().setTitle(title);
}
The activityMonitor variable is a component which holds a reference for the current foreground activity.
It is set upon the onResume() of each activity in the app.
When I run this code, the activity launches only once this method is over, which makes the second command useless, as it sets the previous activity’s title, not the new launched one. Adding a delay before the setting of the title didn’t help.
When I debugged it, I saw that the the code of the second
command is consistently being called before the onCreate() of the required new activity (regardless of the delay I set between the two). My question is why.
Thanks
EDIT - My need better explained:
I know how to pass data to a new activity. I was interested in knowing the reason for this particular timing issue - why does the activity get always launched AFTER the end of this code block/method.
According to my design, this method resides in a separate module, which is only responsible for executing a url (which is turned into a specific intent, according to a url matcher), and allowing a callback to be called after the execution of the url, i.e. after an a activity is launched.
In this example, the callback is actually a call to a method which tries to set the current activity's title (the callback method resides in the app module and is passed to the "url executor" module as an argument).
So now that I explained my need of this sort of generic approach, maybe you could give me tips on how you would do it, without falling into this "activity didn't really launched yet" problem.
Thanks.
If you would like to modify something in the activity being started by the intent I would recommend passing an Extra along with your Intent and getting that extra in the new activity OnCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.xxxxxxxx);
Intent i = getIntent();
setTitle(i.getStringExtra("title");
To put an extra inside an Intent use intent.putExtra("title", "newTitle");
Related
I have coded a custom view and in this view, I have a method. When this method (launchTestActivity) is called, I would like it to launch another activity.
Currently my method looks like this:
private void launchTestActivity() {
Context ctx = getContext();
Intent intent = new Intent(ctx.getApplicationContext(), DeathScreenActivity.class);
ctx.startActivity(intent);
}
However when this method is called, it takes a time to switch to the new activity (which is just a blank screen) and I get a logcat message saying the application is skipping frames.
What do you suggest I should do?
Pretty sure it might be just your CPU or your memory that is taking a while to call this function. You are calling it correctly anyway.
The application may be doing too much work on its main thread. You should check for any heavylifting in the DeathScreenActivity.
Turns out since I was calling launchTestActivity() from within a if statement that was being tested everytime onDraw() was being called I was calling launchTestActivity() multiple times and thus launching the new activity multiple times.
Say i have started activity A with new Intent(context,class) i thats has sensitive data in it, when is this intent gets destroyed? in particular, in what cases among the following would getIntent() in Activity A's code return the exact same intent i?
Press on the activity's task on android's task manager
App icon was clicked and the activity was recreated and brought to front
Ive tried it with my app, iand i get weird results... normally it doesnt get the same intent, but sometimes it seem that it does, so i am not sure whats going on, anyway If i can be returned from any of the upper options how to avoid it?
I think a glance on lifecycle of an Intent would be helpfull if any1 know of any documentation regarding this...
Say i have started activity A with new Intent(context,class) i that's has sensitive data in it, when is this intent gets destroyed?
as long as there's object/class that holds reference to your Intent object - it will not be garbage collected. the Activity (Activity A) holds reference to the intent that started it, so as long as Activity A object is not garbage collected - then i also won't be garbage collected.
important comment: onDestroy() activity callback and class distractor are to different things!!!
in what cases among the following would getIntent() in Activity A's code return the exact same intent i?
assuming you are not calling setIntent() explicitly:
1) Press on the activity's task on android's task manager:
if the activity was previously stopped in reaction to back button navigation or someone called finish() explicitly on it, then the activity passed on the onDestroy() callback. in that case - pressing on the "application" from the recent tasks manager would re-created the activity with a new intent from scratch, and thus - getIntent() would bring this new intent that don't contain your extras or other overloads.
otherwise (the activity was sent to background via home button, or other activity started on top of it) : when you'll launch it back from the recent task - it will be intent object with the original extras you passed it before...
2) App icon was clicked and the activity was recreated and brought to
front
basically the same cases I mentioned in (1) apply to (2) , but basically it depends on two more things:
the intent flags that the specific launcher you are using is overloading on the intent it creates when it launch your activity.
the launch mode and activity flags you overloaded on the intent that you used to start your own activity.
assuming you are not using any of the above, and you are using normal good functional launcher application - the behavior would be exactly as I explained in (1)
I'm using an Intent Filter in my activity to retrive an url clicked on by the user.
In my activity onCreate method I have the following code
Intent intent = getIntent();
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
url = intent.getDataString();
showDialog(DIALOG_ID);
}
It works great except when I rotate my phone. Even if tha dialog was closed prior to the rotation, it reopen every time I change the phone orientation.
I can I avoir that.
For your information I don't want to lock the orientation
Another solution that doesn't require handling configuration changes yourself might be to simply check if the savedInstanceState Bundle parameter in onCreate is null before showing the dialog.
If you look at the docs for onCreate you can see that savedInstanceState will be non-null when the activity is recreated (due to configuration changes for example) and thus will be null when the activity is run fresh.
You would typically call setIntent(null) to remove the intent used to summon the activity. However, in practice, it doesn't always work. Apparently, a common workaround is to set the intent's action or data or both to null, depending on what you use in code. In your case, after showing the dialog, I would probably go with intent.setAction(null).
This is a pretty simple fix. In you manifest file, locate activity and add this:
android:configChanges="keyboardHidden|orientation"
This will prevent your logic in onCreate to fire again (or so I believe)
Quoted from here:
In some special cases, you may want to bypass restarting of your
activity based on one or more types of configuration changes. This is
done with the android:configChanges attribute in its manifest. For any
types of configuration changes you say that you handle there, you will
receive a call to your current activity's
onConfigurationChanged(Configuration) method instead of being
restarted. If a configuration change involves any that you do not
handle, however, the activity will still be restarted and
onConfigurationChanged(Configuration) will not be called.
I have never seen this issue until today. I did getIntent().setAction("");, and solved it. No more brain damage :)
I have two apps that both extend activities and work perfect on their own, but when I call intent of one to view data in the other the app crashes. I have taken the second and made it a separate java file in my app. Also, I have updated the manifest to include this new activity. Where do I call the intent? If all I want from the second activity is for it to get data and return data should I use startactivityforresult instead? The main thing I want to do is get sensor data from the orientation sensor and show it on my display while still running the original activity.
This is how I call the second activity:
Intent intent = new Intent(this, LeanAngle.class);{
startActivity(intent);
Maybe the problem is where I am calling it. Is there a specific place to call it? Also, it has the same view as the main activity does, r.layout.main.
You are calling it correctly. I assume your placement is wrong. It will only work if it is the last thing you call in onCreate(). If that is indeed where it is located.
There is something I don't quite understand right now.
My main activity class creates a Service, which creates a new thread that waits for a TCP connection. Once one comes in, it will start a new activity:
Intent dialogIntent = new Intent(getBaseContext(), VoIPCall.class);
dialogIntent.putExtra("inetAddress", clientSocket.getInetAddress());
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(dialogIntent);
After that, the onCreate() method of that class gets run. It will create 2 threads: one records and send data, the other one receive and plays data. Those threads have a forever while loop.
For some reason, I notice that the onCreate() of that last class gets called again, which makes my program crash. I do not understand why it is called again as only the 2 threads are running, there is no user interaction. The documentation says: "Called when the activity is first created.". The activity is already running and I am not trying to create it.
Could someone please explain me this behavior?
Android will recreate your activity after certain "device configuration changes". One such example is orientation. You can read more here...
http://developer.android.com/guide/topics/resources/runtime-changes.html
Perhaps something in your threads is doing something which is considered a configuration change?
If that's the case you might find it useful to extend the Application class instead and do your initialization there. See this post...
Activity restart on rotation Android
HTH
I was experiencing an Activity called twice on some Samsung devices. I solved it adding android:launchMode = "singleInstance" on the Activity tag on Manifest. I hope this can help.
Similar to this question where orientation change is causing the device to reconfigure:
Activity restart on rotation Android
My preferred answer:
https://stackoverflow.com/a/11811999/3739540
Instead of trying to stop the onCreate() from being fired altogether, maybe try checking the Bundle savedInstanceState being passed into the event to see if it is null or not.
For instance, if I have some logic that should be run when the Activity is truly created, not on every orientation change, I only run that logic in the onCreate() only if the savedInstanceState is null.
Otherwise, I still want the layout to redraw properly for the orientation.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_list);
if(savedInstanceState == null){
setupCloudMessaging();
}
}
This happened to me once when I used "Don't save actions" in the app section of the developer options. Be sure you have turned this off.
I have observed this issue when you are trying start an activity with values in the intent.
Below is an example where Activity_A calls Activity_B and passes values in the intent to be collected in Activity_B:
Intent intent = new Intent(this, activityB.class);
intent.putExtra("val1", someValue1);
intent.putExtra("val2", someValue2);
intent.putExtra("val3", someValue3);
this.StartActivity(intent);
In this case, you can set the android:launchMode="singleInstance" or android:launchModel="singleTop" in your AndroidManifest.xml and Activity_B will only launch once. Hope this helps.