I have an activity with a launch mode set to singleTop in the manifest. However if this activity is started multiple times through startActivity called one after another, multiple instances are still created.
Here is the code that demonstrates the behavior. MainActivity displays a single button that start SingleTopActivity twice when clicked. SingleTopActivity displays a message received from MainActivity.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startActivity = (Button) findViewById(R.id.startActivity);
startActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startSingleTopActivity("first");
startSingleTopActivity("second");
}
});
}
private void startSingleTopActivity(#NonNull String message) {
Intent intent = new Intent(this, SingleTopActivity.class);
intent.putExtra(SingleTopActivity.EXTRA_MESSAGE, message);
startActivity(intent);
}
}
public class SingleTopActivity extends AppCompatActivity {
public static final String EXTRA_MESSAGE = "MESSAGE";
private TextView mMessage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_top);
getSupportActionBar().setTitle("SingleTopActivity");
mMessage = (TextView) findViewById(R.id.message);
mMessage.setText(getIntent().getStringExtra(EXTRA_MESSAGE));
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String message = intent.getStringExtra(EXTRA_MESSAGE);
mMessage.setText(mMessage.getText() + " " + message);
}
}
When no additional intent flags are present SingleTopActivity with second message is launched. When navigated back SingleTopActivity with first message appears instead of MainActivity.
However if launched in debugger (so starting activity takes longer time due to breakpoints etc.), or when flags like FLAG_ACTIVITY_REORDER_TO_FRONT or FLAG_ACTIVITY_CLEAR_TOP are set only one instance of SingleTopActivity is launched, as expected.
Why does singleTop not work as expected in this case?
As this page says, if a activity is set to singletop, only if the activity is in top of the task, it won't be created again.
In your code,when you call startSingleTopActivity("second");,the top activity of the task is MainActivity not SingleTopActivity, so it will be created twice.
Related
What is the problem with my code :(
This is the sending class:
public class Send extends AppCompatActivity {
String message_text;
final static String MSG_KEY = "this.is.the.message";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.send_layout);
}
public void sendMessage(View view) {
EditText entryText = (EditText)findViewById(R.id.message_text);
message_text = entryText.getText().toString();
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(message_text, MSG_KEY);
startActivity(intent);
}
}
this is the receiver:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView theMessage = (TextView)findViewById(R.id.theMessage);
theMessage.setText(getIntent().getStringExtra("this.is.the.message"));
}
}
the app starts but it does not pass text, just an empty recieving activity ???
intent.putExtra(message_text, MSG_KEY);
replace with
intent.putExtra(MSG_KEY, message_text);
Frist argument is NAME , second argument - VALUE
You are using value as key and key as value which is causing this issue.
Change
intent.putExtra(message_text, MSG_KEY);
to
intent.putExtra(MSG_KEY, message_text);
If changing intent.putExtra(MSG_KEY, message_text); doesn't fix the issue. Check AndroidManifest.xml to make sure that MainActivity is not the launcher otherwise your MainActivity starts before the send class.
MyActivity started by another Activity (different process) with extra string value in intent.
If it reboots itself through MyActivity::restart() like following, extra string value will be received again in MyActivity::onCreate(). That is what I do NOT want.
Is it a wrong way to reboot ?
class MyActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
String value = getIntent().getStringExtra("Key");
//Log shows value
}
public void restart()
{
onDestroy();
System.exit(0);
}
}
Suppose we have two simple applications, so we have two different packages.
Each of these packages has an Activity that can be launched by clicking the application icon. Suppose that the two activities are as follows:
MyFirstActivity, which is into the package org.firstexample.firstactivity
MySecondActivity, which is into the package org.secondexample.secondactivity
Suppose we have launched the MyFirstActivity activity, so it is running.
Could the MySecondActivity activity send data directly to the MyFirstActivity activity?
I would like the two activities (which are in different packages) can communicate with each other by exchanging data.
if you are launching MySecondActivity from MyFirstActivity then use this way:
in Activity MyFirstActivity:
Intent intent25 = new Intent(Intent.ACTION_MAIN).addCategory(
Intent.CATEGORY_LAUNCHER).setClassName("org.secondexample",
"org.secondexample.MySecondActivity").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_FROM_BACKGROUND).setComponent(new ComponentName("rg.secondexample",
"org.secondexample.MySecondActivity"));
Bundle bundle = new Bundle();
bundle.putString("Name", "test");
intent25.putExtras(bundle);
getApplicationContext().startActivity(intent25);
and in MySecondActivity oncreate()
Bundle bundle = this.getIntent().getExtras();
String name = bundle.getString("Name");
If you want to pass data without resuming on destroying activity then you have to make listener for that..
public class MyFirstActivity extends Activity implements OnDataChanged {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public void onChange(int a) {
Log.e("", "a : " + a);
}
}
MySecondActivity.java
public class MySecondActivity extends Activity {
private OnDataChanged mOnDataChanged;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sendData(10);
}
public interface OnDataChanged {
public void onChange(int a);
}
private void sendData(int a) {
mOnDataChanged.onChange(a);
}
}
MySecondActivity is sending 10 to MyFirstActivity by implementing listener of MySecondActivity...
I have three classActivity created. One is super class and other sub class and third is HomeActivity.
Code for super class is :
public class MyActivity extends Activity {
Button btnHome = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onHomeClick(View view) {
String LOG_TAG = "Akshar";
System.out.println("Hello11111");
btnHome = (Button) view;
Log.v(LOG_TAG, "index=" + btnHome);
}
}
and my subclass code is :
public class ChooseIsland extends MyActivity {
Button btn_home = null;
MyActivity ob1 = new MyActivity();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chooseiland);
addListenerOnButton();
}
private void addListenerOnButton() {
// TODO Auto-generated method stub
ob1.onHomeClick(btn_home);
}
}
Now I want to go on Home page when click so when I write ?
Intent intent = new Intent(this, HomeActivity.class);
There is no close operation as such in android. You should make sure you do not save anything in stack so whenever you are traversing from one activity to other, make sure you use intent flags to clear history or top of stack and then call finish.
finish() will close the current activity and the previous activity will come to foreground.
Generally to we write finish() method to close activity.
While the application is running, I press the HOME button to close the application. When I start the application again, it resumes on the page displayed prior to clicking on HOME. I want the application to start with the initial display instead. I have used finish() to finish the activity but it is not working. Any suggestions?
Most likely you have several instances of the same activity. To resolve this kind of issues create your own parent Activity class e.g. MyRootActivity which will hold static list of all of available/alive activities:
public class MyRootActivity extends Activity
{
private static final String TAG=MyRootActivity.class.getName();
private static ArrayList<Activity> activities=new ArrayList<Activity>();
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
activities.add(this);
}
#Override
public void onDestroy()
{
super.onDestroy();
activities.remove(this);
}
public static void finishAll()
{
for(Activity activity:activities)
activity.finish();
}
}
For that all of your activities need to be children of MyRootActivity.
Then when you are about to sure that you're closing your application - just call MyRootActivity.finishAll();
Create a static Activity object which activity finish on other activity and assign activity in this i.e you can can add more activities
public class demoActivity extends AppCompatActivity {
public static Activity self_intent;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo_activity);
selfintent=this;
}
//Other functions--------------
}
do same for other activities
on other
public class finishingActivity extends AppCompatActivity {
public Button activityCloseBtn;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.finishing_activity);
activityCloseBtn= (Button) view.findViewById(R.id.activity_close_btn);
activityCloseBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
demoActivity.selfintent.finish(); //for finish demoActivityactivity
//for other activities Activity.selfintent.finish();
finish(); //for finish current activity
}
});
try calling super.onPause() first and later call finish() inside your onPause() stub