Start activity from another without loading the first's layout - android

My launcher activity may start another on a certain condition, it looks something like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefManager = new PreferenceManager();
if (prefManager.startMain(this)) {
startActivity(new Intent(this, MainActivity.class));
finish();
return;
}
setContentView(R.layout.activity_wizard);
...
...
PreferenceManager is just a helper for easy access to SharedPreferneces.
If the condition is true, a flashing of the first activity layout is shown and only then the second activity starts.
I want to skip the flashing of the first activity layout when starting the second (I actually expected this since I don't call setContentView but apparently, it isn't).
I thought about creating a 3rd, transparent layout activity which starts the correct activity but I hope there is a better way.

Switch the startActivity() and finish() around so finish() is called first, haven’t been able to test but could be
if (prefManager.startMain(this)) {
finish()
startActivity(new Intent(this, MainActivity.class));
}
Shouldn’t be a need to call return either

Related

When good time to start another activity

I have an Android Best Practice question. I have to following code, which is working nicely, but I think it is not so elegant. So, my question is: at which point of activity life cycle is nice to start another activity ?
public class LoginActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ParentPreferences parentPreferences = new ParentPreferences(getApplicationContext());
if (parentPreferences.isPassExists()) {
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
} else {
setContentView(R.layout.login);
}
}
}
The task is about: if the parent has already made a password to protect the app, than we don't need to show the LoginActivity. I don't know, is it "healthy" for an Activity to give an intent to launch, when nor the onCreate nor the other lifecycle methods completed.
What are you thoughts guys ?
I think the better way is to create LauncherActivity, and start activitys from them:
For example:
public class LauncherActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ParentPreferences parentPreferences = new ParentPreferences(getApplicationContext());
Intent intent;
if (parentPreferences.isPassExists()) {
intent = new Intent(this, MainActivity.class);
} else {
intent = new Intent(this, LoginActivity.class);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
startActivity(i);
}
}
Updated:
Refering to Activity | Android Developer
onCreate is a first lifecycle method, сonsequently better to start activity B when A activity just started and does not inflate any layout
I would have the manifest start your MainActivity or whatever you call it. The MainActivity starts by checking if the user has logged in. If not, it starts your LoginActivity, which comes back in onActivityResult() with the result of the login.
It does depend on the requirement for the user to log in every time they start the app, or just once, or once in a while. If the use has to log in every time, than it's ok to start with LoginActivity. Otherwise, starting LoginActivity every time and passing to MainActivity (or whatever) seems just a waste. "Waste" not in the sense of performance, but of clarity of your app.
I think the best solution for you is to add a SplashScreen or like a "fake" screen.
Here you check if he's logged in already and based on it you start the correct activity.
Maybe the absolutely best way would be to do it with fragments, but you have to change a lot of your app.
About when to call it, the onCreate is perfect :)

return to the same activity, When restart the app

I have a lot of activities in my app, and I want that if the user closes the app in activity 13 for example, when opening the app at another time the activity returns in activitty n° 13. how can I do this? thank in advance
You could use SharedPreferences to keep track of the last used activity.
Then you can redirect the user in the onCreate of your main activity to the correct activity, and call finish on your main activity.
This could look something like this:
#Override
protected void onCreate(Bundle savedInstanceState)
(...)
int last_activity = getLastActivityIdFromSharedPreferences();
if (last_activity == 1)
{
this.startActivity(new Intent(this, ActivityOne.class));
finish();
}
(...)
}

How to capture launched finished activity in Android?

I need to do something ( like show an alert ) after my activity launched completely.
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
How to do it?
You'll have to do it in the onCreate of the SignInActivity class as the the first one will go to background and will no longer be able to display stuff on the screen, at least not directly
Whats the problem then!!
You can use the onCreate, onResume of started activity
Intent intent = new Intent(this, SignInActivity.class); startActivity(intent);
after this in SignInActivity use your alert
#Override
protected void onCreate(Bundle bundle)
{
super.onCreate(bundle);
setContentView(R.layout.player);
// Put your alert as the last statement of this method
}
OR
#Override
protected void onResume()
{
// put your alert here
super.onResume();
}
Note: onResume is called every time the activity is resumed
You should take a look at the activity lifecycle document from the official Android docs. As you can see you will receive a callback to one of three methods as your activity launches. If you only want to show it when the activity is first shown you can show the alert dialog in the onCreate call. You could also place it in the onResume call if you would like the dialog to show every time the user leaves this activity and comes back to it. Read through the doc, you'll have a better understanding of how an activity lives inside your application. Below is a quick example of where to place the code.
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AlertDialog.Builder(this)
.setMessage("Hello Android")
.show();
}
}

Find out whether the current activity will be task root eventually, after pending finishing activities have disappeared

If FirstActivity is the root of the task, and it finishes itself and launches SecondActivity, then calling isTaskRoot() in SecondActivity immediately will return false, because the FirstActivity's finishing happens asynchronously and thus isn't done yet. Waiting for a second and then calling isTaskRoot() returns true.
public class FirstActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
finish();
startActivity(new Intent(this, SecondActivity.class));
}
}
public class SecondActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
protected void onResume() {
super.onResume();
((TextView)findViewById(R.id.tv1))
.setText("isTaskRoot() in onResume(): " + isTaskRoot());
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
((TextView)findViewById(R.id.tv2))
.setText("isTaskRoot() after 1s: " + isTaskRoot());
}
}, 1000);
}
}
Is there a way to …
(optimally) find out whether the activity will be the task root eventually, or,
(better than nothing) get some sort of notification/callback once the task is in its "final" state and thus isTaskRoot() will return the "truth"?
I've had a similar problem and I wanted tight control over exactly who the root activity is. In my case, the root could only be one of my own activities (not 3rd party ones), so I was able to use the following approach:
I extended the Application class, added a weak reference to an activity called currentRootActivity and added synchronized getter and setter.
Then I managed this state by myself when activities were created / destroyed. My use case was a little special because I was looking to replace one root with another, so I knew exactly where to reset my new state variable, but I'm pretty sure you can do the same.
I was even able to add this state logic in a shared base class for all of my activities. So this wasn't as disgusting as it sounds :)
As mentioned in the comments, the activity method isFinishing might also come in handy.
Try:
Intent intent = new Intent(this, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
I expect that this will make SecondActivity the root activity.

onResume() not called second time an Activity is launched

During the normal course of development, I noticed that a particular activity appears to have stopped responding the second time it is called.
i.e. menu->(intent)->activity->(back button)->menu->(intent)
There is nothing relevant in logcat.
I don't even know where to start debugging this nor what code to show so here are the onClick and onResume fragments:
if (!dictionary.getClassName().equals("")) {
this.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent i;
i = new Intent(mContext, NVGlobeNavigatorVC.class);
i.putExtra("PAGE_TITLE", title);
i.putExtra("TITLE", _dictionary._title);
mContext.startActivity(i);
});
} else {
findViewById(R.id.greaterthan).setVisibility(View.GONE);
}
and in the Activity being launched:
#Override
protected void onResume() {
super.onResume();
...
Nothing unusual in manifest either:
<activity
android:name=".NVViews.NVGlobeNavigatorVC"
android:theme="#style/WindowTitleBackground"
android:label="GlobeNavigator"/>
For clarity, I put breakpoints on mContext.startActivity(i) and super.onResume(). I click the view with the onClickListener and both breakpoints are hit as expected. I then press the back button which returns me to the menu. onPause() is called as expected.
I touch the view to launch the activity again, and the breakpoint on startActivity is hit but not in onResume() in the target activity. The screen goes black and the only way I can get going again is to restart the app. If I pause the debugger, it pauses in dalvik.system.NativeStart() which implies that the activity is never relaunched.
I don't think it's relevant, but I'm using Intellij IDEA and have deleted all of the output directories, invalidated the caches and done a full rebuild.
Target API is 8. I've tested on 2.3 and 4.0.4.
Any ideas? I'm stumped.
[EDIT]
In onPause, I save some stuff to prefs. The purpose of onResume() is to get them back again:
#Override
protected void onPause() {
super.onPause();
SCPrefs.setGlobeViewViewPoint(globeView.getViewPoint());
SCPrefs.setGlobeViewZoom(globeView.getZoom());
SCPrefs.setGlobeViewScale(globeView.getScale());
}
This code:
i = new Intent(mContext, NVGlobeNavigatorVC.class);
creates a new intent. The intent is of class NVGlobeNavigatorVC.class.
If you call it once, you create a new activity, lets call it "iTheFirst". If you back out of the activity, it executes "on pause". When you run the above code again, you create another new activity of the same class, but a different acitivity. Hence it won't resume your other activity, but make a new one that we could call "iTheSecond". It looks just like iTheFirst but is unique.
If you want to resume the above, after backing out of it, you need to keep a reference to it in your menu. Then in your onClick, look to see if that activity exists, and if not, make a new one and start it, and if it does exist, just resume it.
Here is a sample activity that remembers and restarts an activity:
Intent savedCueCardActivity = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState, R.layout.landing);
}
public void goToNextScreen(View v) {
if (savedCueCardActivity == null) {
savedCueCardActivity = new Intent().setClass(this, CueCardActivity.class);
startActivity(savedCueCardActivity);
// lastActivity.finish();
} else {
savedCueCardActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(savedCueCardActivity);
}
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
I found the problem, and it's a bit esoteric.
I have a large static data structure which is loaded in a class static initialiser. There was a bug in that initialiser causing an infinite loop the second time it was called if the data structure was still loaded.
Because that class is referenced in my Activity, the class loader is loading it before onCreate() or onResume() is called.
The loop gave the appearance that the Activity loader had hung.

Categories

Resources