在 Android 中启动新 Activity 的正确方法是什么?
在开发我的第一个 Android 应用程序时,我想出了 3 种不同的方法来启动新活动(可能还有更多我不知道的方法),我无法理解它们是否不同或者它们是否基本上以相同的方式工作方式。
例如,我有一个带有菜单的 MainActivity
(它是一个 ActionBar 组件,但工作方式就像菜单一样)。菜单中有一个打开AboutActivity
的选项。
我的第一种方法是这样的:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);
getMenuInflater().inflate(R.menu.actionbar_main, actionBar.asMenu());
actionBar.findAction(R.id.actionbar_item_home).setIntent(new Intent(this, AboutActivity.class));
}
}
我的第二种方法,为了简化代码组织,我开始用自己的方法处理所有菜单项选择,如下所示:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);
getMenuInflater().inflate(R.menu.actionbar_main, actionBar.asMenu());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.actionbar_item_home:
item.setIntent(new Intent(this, AboutActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
第三种方法与前一种方法非常相似,唯一的不同之处在于开始的代码行AboutActivity
。而不是:
item.setIntent(new Intent(this, AboutActivity.class));
我改为:
startActivity(new Intent(this, AboutActivity.class));
但这让我思考处理这个问题的正确方法。我的问题:
- 方法#2 和#3 之间有什么区别吗?在我看来,setIntent 基本上是在每次选择菜单项时定义菜单项意图。我认为这是一件坏事?而
startActivity
就是这样做的。但话又说回来,每次选择该项目时都会创建一个新的意图,这引出了下一个问题。 - 在方法 #1 中,我没有这个问题,意图仅在活动的 onCreate 方法中创建一次(我相信只要活动没有被破坏)。但是性能/内存方面(或其他可能相关的东西),以下之间有什么区别吗?
- a) 在
onCreate
方法中设置一次意图 - b) 在
onOptionsItemSelected
菜单处理程序中启动活动
- a) 在
- 现在,假设一个文本字段位于
关于活动
。我按下菜单项并打开活动,在文本字段中键入任何内容,返回,再次按下菜单项,文本就消失了。我认为只创建一次意图(方法#1),活动状态将持续并且文本字段将被填充。但事实并非如此,它的行为与所有其他方法完全相同,这让我更加困惑。它们之间有什么区别?
While developing my first Android app I've come up with 3 different ways to start a new activity (there' probably more that I'm unaware of) and I can't understand if they are different or if they basically work in the same way.
For instance, I have a MainActivity
with a menu (it's an ActionBar component but works just like a menu). The menu has an option to open the AboutActivity
.
My first approach was this:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);
getMenuInflater().inflate(R.menu.actionbar_main, actionBar.asMenu());
actionBar.findAction(R.id.actionbar_item_home).setIntent(new Intent(this, AboutActivity.class));
}
}
My second approach, to simplify code organization, I started handling all menu item selections in their own method like this:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);
getMenuInflater().inflate(R.menu.actionbar_main, actionBar.asMenu());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.actionbar_item_home:
item.setIntent(new Intent(this, AboutActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
The third approach is very similar to the previous one, the only different is in the code line that starts the AboutActivity
. Instead of:
item.setIntent(new Intent(this, AboutActivity.class));
I changed to:
startActivity(new Intent(this, AboutActivity.class));
But this got me thinking on the proper way to handle this. My questions:
- Between the approach #2 and #3, are there any differences between them? The way I see it,
setIntent
is basically defining the menu item Intent every time the item is selected. Which I'm assuming is a bad thing to do? WhilestartActivity
does just that. But then again, a new intent is created every time the item is selected, which leads me to the next question. - On approach #1 I don't have that issue, the intent is only created once in the
onCreate
method of the activity (as long as the activity is not destroyed I believe). But performance/memory wise (or anything else which might be relevant), are there any differences between the following?- a) Set the intent once in the
onCreate
method - b) Start the activity in the
onOptionsItemSelected
menu handler
- a) Set the intent once in the
- Now, assume a text field is on the
AboutActivity
. I press the menu item and open the activity, type anything in the text field, go back, press the menu item again and the text is gone. I though that creating the intent only once (approach #1) that the activity state would persist and the text field would be filled. But it doesn't, it just acts exactly like all all other approaches, which confuses me even more. What are the differences between them all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
2 是浪费的,因为就像你所说的那样,它每次被调用时都会创建该意图。这并不是非常浪费,因为这些方法没有被太多调用,但这不是最佳实践。
如果您想做类似选项 1 的操作,但位置更好,onCreateOptionsMenu() 将是最佳选择。
“菜单”是启动活动的特例。通常你会做像#3这样的事情,只要你需要它,你就可以调用startActivity。菜单的 setIntent 只是在幕后执行此操作。
我还认为有一种方法可以通过 XML 来做到这一点。但我很难确定。
2 is wasteful, since like you said it's creating that intent every time it's called. It's not terribly wasteful since these methods are not being called much, but it's not a best practice.
If you wanted to do something like option 1 but in a better location, onCreateOptionsMenu() would be the best choice.
The "menus" are a special case for starting an activity. Normally you do something like #3 where you just call startActivity whenever you need it. The setIntent for menu's just does that behind the scenes.
I also think there's a way to do this via XML. But I'm having trouble finding out for sure.