Who can explain the following behavior?
First activity:
public class MainActivity extends AppCompatActivity {
public void onClick(View view) {
startActivity(new Intent(this, SecondActivity.class));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
Log.d(">>><<<", "onStart: " + getClass().getSimpleName());
}
#Override
protected void onStop() {
super.onStop();
Log.d(">>><<<", "onStop: " + getClass().getSimpleName());
}
#Override
protected void onPause() {
super.onPause();
Log.d(">>><<<", "onPause: " + getClass().getSimpleName());
}
#Override
protected void onResume() {
super.onResume();
Log.d(">>><<<", "onResume: " + getClass().getSimpleName());
}
}
Second activity:
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
}
#Override
protected void onStart() {
super.onStart();
Log.d(">>><<<", "onStart: " + getClass().getSimpleName());
}
#Override
protected void onStop() {
super.onStop();
Log.d(">>><<<", "onStop: " + getClass().getSimpleName());
}
#Override
protected void onPause() {
super.onPause();
Log.d(">>><<<", "onPause: " + getClass().getSimpleName());
}
#Override
protected void onResume() {
super.onResume();
Log.d(">>><<<", "onResume: " + getClass().getSimpleName());
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:onClick="onClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click here!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"
android:theme="#style/Transparent"/>
</application>
</manifest>
Styles:
<style name="Transparent" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
</style>
Steps to reproduce:
Turn on "Don't keep activities" option in "Developer options" for simple reproducing.
Launch the app and press the button to call the second activity.
Press Home button.
Go back to the app.
Expected logs after step #4:
onStart: MainActivity
onStart: SecondActivity
onResume: SecondActivity
Actual logs after step #4:
onStart: MainActivity
onResume: MainActivity
onStart: SecondActivity
onResume: SecondActivity
Why MainActivity resumes? Why doesn't pause after resume before start SecondActivity?
Related
The splash activity shows just blank screen. Code is below :
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class SplashScreen extends AppCompatActivity {
private static int SPLASH_TIME_OUT = 3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
try {
Log.v(" gonna AsyncTask"," execute AsyncTask");
new AsyncTask<String, String, String>() {
#Override
protected void onPreExecute() {
Log.v(" PreExecute AsyncTask"," execute AsyncTask");
}
#Override
protected String doInBackground(String... arg0) {
Log.v(" in doInBackground"," execute AsyncTask");
try {
Log.v(" sleep doInBackground"," execute AsyncTask");
Thread.sleep(SPLASH_TIME_OUT);
} catch (Exception e) {
Log.v(" Exception "," execute AsyncTask");
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String unused) {
Log.v(" onPostExecute "," execute AsyncTask");
Intent i = new Intent(SplashScreen.this,
MainActivity.class);
Log.v(" starting Activity "," execute AsyncTask");
startActivity(i);
}
}.execute();
} catch (Exception e) {
e.printStackTrace();
}
}// end of onCreate
}// end of class SplashScreen
The XML layout file has :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_splash_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.istiaqueahmed.archeology.SplashScreen">
<ImageView
android:id="#+id/splash_img"
android:layout_width="170dp"
android:layout_height="112dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="130dp"
android:src="#drawable/splash"
/>
<TextView
android:id="#+id/developed_by"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="#string/developed_by"
android:layout_below="#id/splash_img"
android:textStyle="bold"
android:textSize="13sp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp"
/>
</RelativeLayout>
Android manifest file has -
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
>
<activity
android:name=".SplashScreen"
android:noHistory="true"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
........
</application>
And the style.xml has -
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
Perhaps the activity needs some time for setContentViewto execute and meanwhile the app goes to the MainActivity.
How to prevent the app from showing the blank screen and instead show the splash screen for the intended time period?
Your App is freeze because you are sleeping main Thread.
Thread.sleep(SPLASH_TIME_OUT); // This will sleep your main thread.
Instead of AsyncTask use Handler with delay.
Use CountDownTimer instead of AsyncTask.
private static long SPLASH_TIME_OUT = 3000;
new CountDownTimer(SPLASH_TIME_OUT, 1000) {
public void onTick(long millisUntilFinished)
{
}
public void onFinish()
{
Intent i = new Intent(SplashScreen.this,
MainActivity.class);
startActivity(i);
}
}.start();
There is no need to used AsyncTask here.
Please try this code which helps you.
public class WelcomeActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
startHandler();
}
private void startHandler() {
Runnable runnable = new Runnable() {
#Override
public void run() {
Intent i = new Intent(WelcomeActivity.this, MainActivity.class);
startActivity(i);
finish();
}
};
Handler handler = new Handler();
handler.postDelayed(runnable, 3000);
}
}
I have an activity that listens to preference changes and reloads the app. I am using recreate() to do that. But I don't know how to pass in arguments through that, so I have resorted to manual activity reloading.
Intent intent = getIntent();
finish();
// add in the arguments as Extras to the intent
startActivity(intent);
This has the behaviour I want, but the recreating of the activity isn't smooth for the user as they will see the activity being killed and the same activity relaunching. I want the user to not be aware that the activity was relaunched. So, my question is can I use the method recreate() and still pass arguments through it.
You can set the data on the activity's intent before calling recreate
getIntent().putExtra("RECREATE_DATA", "Some Data");
recreate()
since when you recreate the activity the same activity instance is used, the data in the intent will still be there after recreate.
You can try this way:
You can restart you activity with launch Mode as SingleTop and handle the onNewIntent(Intent intent) method. This way you are restarting the activity and send the intent, along with this activity is not being Killed i.e. oncreate of your activity will not be called.
public class MainActivity extends Activity implements View.OnClickListener {
Button btn ;
String mRelaunchData ;
public static String TAG = "RelaunchMainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.button);
btn.setOnClickListener(this);
Log.e(TAG, "onCreate called");
}
#Override
public void onClick(View view) {
Log.e(TAG, "onClick called");
Intent intent = new Intent("relaunch.activity.ACTIVITY_SELF_START_INTENT").setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("RESTART_DATA", "This is relaunch of this Activity");
startActivity(intent);
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e(TAG, "onNewIntent called");
mRelaunchData = intent.getStringExtra("RESTART_DATA");
Log.e(TAG, "mRelaunchData =" + mRelaunchData);
}
#Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume called");
if(mRelaunchData != null){
Toast.makeText(MainActivity.this, mRelaunchData, Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onPause() {
super.onPause();
Log.e(TAG, "onPause called");
}
#Override
protected void onStart() {
super.onStart();
Log.e(TAG, "onStart called");
}
#Override
protected void onStop() {
super.onStop();
Log.e(TAG, "onStop called");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy called");
}
}
in AndroidManifest.xml
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="relaunch.activity.ACTIVITY_SELF_START_INTENT" />
<category android:name = "android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
onClick will relaunch the Activity.
LifeCycle will be
-onclick
-onPause
-onNewIntent
-onResume
I tried to learn LocalBroadcastManager. Searched in web and implemented a simple app with Two activity to perform LocalBroadcastManager. But it's not working. I can't found what's wrong with my code. please help me!
here is my code.
FirstActivity.java
public class FirstActivity extends Activity {
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(FirstActivity.this, SecondActivity.class));
Intent intent = new Intent("localReceiver");
LocalBroadcastManager.getInstance(FirstActivity.this).sendBroadcast(intent);
}
});
} }
SecondActivity.java
public class SecondActivity extends Activity {
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
textView = (TextView) findViewById(R.id.hi_text);
LocalBroadcastManager.getInstance(this).registerReceiver(message, new IntentFilter("localReceiver"));
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(message);
}
private BroadcastReceiver message = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("SecondActivity", "Receiver Initiated...");
textView.setText("Intent receiver activated");
}
}; }
AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".FirstActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"
android:windowSoftInputMode="adjustResize|stateHidden"
android:label="SecondActivity" />
</application>
you are broadcasting something from FirstActivity, and you expect that SecondActivity receives it. In order this to happen you should be able to run two different Activitys at the same time, which is, by design, not possible. By the time you broadcast the string, you don't have anybody listening for it. Try using a Service to broadcast the String, with the receiving Activity resumed, and it will work
SecondActivity would looks like this:
private BroadcastReceiver uiUpdateReceiver;
onStart():
#Override
protected void onStart() {
LocalBroadcastManager.getInstance(SecondActivity.this).registerReceiver((uiUpdateReceiver), new IntentFilter("Your_Data");
super.onStart();
}
onCreate():
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
uiUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
}
onStop():
#Override
protected void onStop() {
LocalBroadcastManager.getInstance(ChatActivity.this).unregisterReceiver(uiUpdateReceiver);
super.onStop();
}
Hope it will help you.
The next process is simple to understand and to reproduce but leads to a bug:
activityA starts an activityB in its onCreate() method
activityB is created and I call finish() in its onResume() method
activityB onDestroy() is called
activityA onResume() is called
and here in activityA, I click a menu button to call finish() - or press the back key.
activityA is removed but onDestroy() is NOT called and A is still living ( adb shell dumpsys 'myPackageName' indicates too many living Activities )
Code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gleroy.com.algo">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".activity.MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="gleroy.com.algo.activity.FakeA"
android:label="#string/app_name"></activity>
<activity
android:name="gleroy.com.algo.activity.FakeB"
android:label="#string/app_name"></activity>
</application>
</manifest>
Activity A :
public class FakeA extends Activity {
private final static String TAG = FakeA.class.getCanonicalName();
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate, taskId :" + getTaskId());
super.onCreate(savedInstanceState);
Intent intent = new Intent(FakeA.this, FakeB.class);
startActivity(intent);
}
#Override
protected void onResume() {
Log.d(TAG, "onResume");
super.onResume();
}
#Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.stop_session_menu_item:
/* stop and quit */
finish();
return false;
}
return super.onOptionsItemSelected(item);
}
}
Activity B :
public class FakeB extends Activity {
private final static String TAG = FakeB.class.getCanonicalName();
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate, taskId :"+getTaskId());
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume, isFinishing :" + isFinishing());
finish();
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
}
Activity A is started from MainActivity which contains a simple button :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FakeA.class);
startActivity(intent);
}
});
So I know that we can't be sure that onDestroy() is gonna be called but here my ActivityA is clearly leaking.
Also I observed that if I use a Timer and TimerTask to delay startActivity in ActivityA or finish() in ActivityB then I don't have this bug anymore.
Here are the events :
FakeA onCreate, taskId :154
FakeA onResume
FakeA onPause, isFinishing : false
FakeB onCreate, taskId :154
FakeB onResume, isFinishing :false
FakeA onResume
FakeB onDestroy
call finish or press back key : FakeA onPause, isFinishing : true
In place of finish() try finishAffinity().
As far as i know:
finish() just destroys the current live Activity
while, finishAffinity() destroys all active Activities.
The best solution was simply to detect whether or not it is useful to start Activity FakeB.
I need to know if the following flow is normal:
Activity A onPause is called because activity B took the focus, but a few seconds later, when activity B is finished and before onStop & onDestroy of Activity A were called, Activity A (same instance) onResume is called.
I have noHistory=true in the activity A defition in the manifest.
I thought that an instance of an activity with noHistory=true will never be returned once the activity has lost it's focus.
The behavior you describe with ActivityA.onResume() being called is not correct. I suspect a typo in your AndroidManifest.xml file. Can you post it and show us?
The timing of onStop() and onDestroy() are a little less defined. Here's an example that works, but onStop() and onDestroy() aren't called until the user hits the back button (but onResume() is never called). If I call finish() after launching ActivityB then they're called on ActivityA earlier.
OUTPUT without finish():
D/HelloAndroidActivity(13013): [HelloAndroidActivity.java:19:onCreate()] onCreate()com.example.hello.HelloAndroidActivity#4055d2e8
D/HelloAndroidActivity(13013): [HelloAndroidActivity.java:45:onStart()] onStart()com.example.hello.HelloAndroidActivity#4055d2e8
D/HelloAndroidActivity(13013): [HelloAndroidActivity.java:39:onResume()] onResume()com.example.hello.HelloAndroidActivity#4055d2e8
NEXT!
D/HelloAndroidActivity(13013): [HelloAndroidActivity.java:51:onPause()] onPause()com.example.hello.HelloAndroidActivity#4055d2e8
D/GoodbyeAndroidActivity(13013): [GoodbyeAndroidActivity.java:16:onCreate()] onCreate()
D/GoodbyeAndroidActivity(13013): [GoodbyeAndroidActivity.java:32:onStart()] onStart()
D/GoodbyeAndroidActivity(13013): [GoodbyeAndroidActivity.java:26:onResume()] onResume()
[BACK]
D/GoodbyeAndroidActivity(13013): [GoodbyeAndroidActivity.java:38:onPause()] onPause()
D/HelloAndroidActivity(13013): [HelloAndroidActivity.java:57:onStop()] onStop()com.example.hello.HelloAndroidActivity#4055d2e8
D/HelloAndroidActivity(13013): [HelloAndroidActivity.java:63:onDestroy()] onDestroy()com.example.hello.HelloAndroidActivity#4055d2e8
D/GoodbyeAndroidActivity(13013): [GoodbyeAndroidActivity.java:44:onStop()] onStop()
D/GoodbyeAndroidActivity(13013): [GoodbyeAndroidActivity.java:50:onDestroy()] onDestroy()
OUTPUT with finish:
D/HelloAndroidActivity(13113): [HelloAndroidActivity.java:19:onCreate()] onCreate()com.example.hello.HelloAndroidActivity#4051b940
D/HelloAndroidActivity(13113): [HelloAndroidActivity.java:45:onStart()] onStart()com.example.hello.HelloAndroidActivity#4051b940
D/HelloAndroidActivity(13113): [HelloAndroidActivity.java:39:onResume()] onResume()com.example.hello.HelloAndroidActivity#4051b940
NEXT!
D/HelloAndroidActivity(13113): [HelloAndroidActivity.java:51:onPause()] onPause()com.example.hello.HelloAndroidActivity#4051b940
D/GoodbyeAndroidActivity(13113): [GoodbyeAndroidActivity.java:16:onCreate()] onCreate()
D/GoodbyeAndroidActivity(13113): [GoodbyeAndroidActivity.java:32:onStart()] onStart()
D/GoodbyeAndroidActivity(13113): [GoodbyeAndroidActivity.java:26:onResume()] onResume()
D/HelloAndroidActivity(13113): [HelloAndroidActivity.java:57:onStop()] onStop()com.example.hello.HelloAndroidActivity#4051b940
D/HelloAndroidActivity(13113): [HelloAndroidActivity.java:63:onDestroy()] onDestroy()com.example.hello.HelloAndroidActivity#4051b940
[BACK]
D/GoodbyeAndroidActivity(13113): [GoodbyeAndroidActivity.java:38:onPause()] onPause()
D/GoodbyeAndroidActivity(13113): [GoodbyeAndroidActivity.java:44:onStop()] onStop()
D/GoodbyeAndroidActivity(13113): [GoodbyeAndroidActivity.java:50:onDestroy()] onDestroy()
HelloAndroidActivity.java:
public class HelloAndroidActivity extends Activity {
private static final String TAG = "HelloAndroidActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate()" + this);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(HelloAndroidActivity.this,
GoodbyeAndroidActivity.class);
startActivity(i);
// Uncomment this:
finish();
}
});
}
#Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume()" + this);
}
#Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart()" + this);
}
#Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause()" + this);
}
#Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop()" + this);
}
#Override
public void onDestroy() {
super.onStop();
Log.d(TAG, "onDestroy()" + this);
}
}
GoodbyeAndroidActivity.java:
public class GoodbyeAndroidActivity extends Activity {
private static final String TAG = "GoodbyeAndroidActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.goodbye);
}
#Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
}
#Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart()");
}
#Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause()");
}
#Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop()");
}
#Override
public void onDestroy() {
super.onStop();
Log.d(TAG, "onDestroy()");
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/hello_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
/>
<Button
android:id="#+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="NEXT!"
/>
</LinearLayout>
goodbye.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/hello_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Goodbye!!!"
/>
</LinearLayout>
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hello"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10"/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name="com.example.hello.HelloAndroidActivity"
android:label="#string/app_name" android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.hello.GoodbyeAndroidActivity">
</activity>
</application>
</manifest>
It sounds like #Sam Quest has your answer. Call onFinish() before launching a new activity. If it happened due to user navigation then your activity should be finished but I don't know if there is any guarantee when. If your LoginActivity is creating the activity then calling onFinish() sounds like the right thing to do, not a workaround.
use on activity result. Then your problem will solve.