我刚刚浏览了Android Developer Site,刷新了Activity生命周期,在每个代码示例中,父类(super class)方法旁边都有一条注释,上面写着“始终首先调用父类(super class)方法”。
虽然这在创建半周期:onCreate、onStart 和 onResume 中是有意义的,但我对销毁半周期的正确过程有点困惑:onPause、onStop、onDestroy。
在销毁特定于实例的资源可能依赖的父类(super class)资源之前,首先销毁实例特定的资源是有意义的,而不是相反。但评论表明并非如此。我错过了什么?
编辑:由于人们似乎对问题的 Intent 感到困惑,我想知道以下哪项是正确的? 为什么?
1.Google 建议
@Override
protected void onStop() {
super.onStop(); // Always call the superclass method first
//my implementation here
}
2.另一种方式
@Override
protected void onStop() {
//my implementation here
super.onStop();
}
最佳答案
Destroying the instance specific resources first, before destroying superclass resources that the instance specific resources may depend upon makes sense, not the other way round. But the comments suggest otherwise. What am I missing?
在我看来:不是一件事。
Mark(又名 CommonsWare on SO)的这个回答阐明了这个问题:Link - Should the call to the superclass method be the first statement? .但是,您可以在他的回答中看到以下评论:
But why official doc says: "Always call the superclass method first" in onPause()?
回到第一格。好吧,让我们从另一个角度来看这个。我们知道 Java 语言规范没有指定必须放置对 super.overridenMethod() 的调用的顺序(或者是否必须放置调用)。
在类 Activity 的情况下,super.overridenMethod() 调用是必需的并且强制:
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStop()");
}
mCalled 在 Activity.onStop() 中设置为 true。
现在,唯一需要讨论的细节是排序。
我也知道两者都有效
当然。查看Activity.onPause()的方法体:
protected void onPause() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);
// This is to invoke
// Application.ActivityLifecyleCallbacks.onActivityPaused(Activity)
getApplication().dispatchActivityPaused(this);
// The flag to enforce calling of this method
mCalled = true;
}
无论您采用哪种方式调用 super.onPause(),都可以。 Activity.onStop() 有一个类似的方法体。但是看看Activity.onDestroy():
protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;
// dismiss any dialogs we are managing.
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}
// close any cursors we are managing.
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}
// Close any open search dialog
if (mSearchManager != null) {
mSearchManager.stopSearch();
}
getApplication().dispatchActivityDestroyed(this);
}
在这里,排序可能可能很重要,具体取决于您的 Activity 设置方式,以及调用 super.onDestroy() 是否会干扰后面的代码。
最后一句话,始终首先调用父类(super class)方法这句话似乎没有太多证据支持它。更糟糕的是(对于语句)以下代码取自 android.app.ListActivity:
public class ListActivity extends Activity {
....
@Override
protected void onDestroy() {
mHandler.removeCallbacks(mRequestFocus);
super.onDestroy();
}
....
}
并且,来自 android sdk 中包含的 LunarLander 示例应用程序:
public class LunarLander extends Activity {
....
@Override
protected void onPause() {
mLunarView.getThread().pause(); // pause game when Activity pauses
super.onPause();
}
....
}
总结和值得一提:
用户 Philip Sheard :提供一个场景,如果使用 startActivityForResult(Intent) 启动 Activity,则必须延迟对 。使用 super.onPause() 的调用setResult(...) after super.onPause() 设置结果将不起作用。他后来在对他的回答的评论中澄清了这一点。
User Sherif elKhatib:解释为什么让父类(super class)首先初始化其资源并最后销毁其资源的逻辑:
Let us consider a library you downloaded which has a LocationActivity that contains a getLocation() function that provides the location. Most probably, this activity will need to initialize its stuff in the onCreate() which will force you to call the super.onCreate first. You already do that because you feel it makes sense. Now, in your onDestroy, you decide you want to save the Location somewhere in the SharedPreferences. If you call super.onDestroy first, it is to a certain extent possible that getLocation will return a null value after this call because the implementation of LocationActivity nullifies the location value in the onDestroy. The idea is that you wouldn't blame it if this happens. Therefore, you would call super.onDestroy at the end after you're done with your own onDestroy.
他继续指出:如果子类与父类适当隔离(在资源依赖方面),则 super.X() 调用不需要遵守任何顺序规范.
请参阅他在此页面上的回答,以通读 super.onDestroy() 调用 确实 影响程序逻辑的场景。
来自 Mark 的回答:
Methods you override that are part of component creation (onCreate(), onStart(), onResume(), etc.), you should chain to the superclass as the first statement, to ensure that Android has its chance to do its work before you attempt to do something that relies upon that work having been done.
Methods you override that are part of component destruction (onPause(), onStop(), onDestroy(), etc.), you should do your work first and chain to the superclass as the last thing. That way, in case Android cleans up something that your work depends upon, you will have done your work first.
Methods that return something other than void (onCreateOptionsMenu(), etc.), sometimes you chain to the superclass in the return statement, assuming that you are not specifically doing something that needs to force a particular return value.
Everything else -- such as onActivityResult() -- is up to you, on the whole. I tend to chain to the superclass as the first thing, but unless you are running into problems, chaining later should be fine.
Bob Kerns 来自 this thread :
It's a good pattern [(the pattern that Mark suggests above)], but I've found some exceptions. For example, the theme I wanted to apply to my PreferenceActivity wouldn't take effect unless I put it before the superclass's onCreate().
用户 Steve Benett 也注意到了这一点:
I only know one situation, where the timing of the super call is necessary. If you wanna alter the standard behavior of the theme or the display and such in onCreate, you have to do it before you call super to see an effect. Otherwise AFAIK there is no difference at which time you call it.
用户 Sunil Mishra 确认在调用 Activity 类的方法时顺序(很可能)不起作用。他还声称首先调用父类(super class)方法被认为是最佳实践。但是,我无法证实这一点。
User LOG_TAG :解释为什么调用父类(super class)构造函数 需要在所有其他事情之前。在我看来,这种解释并没有增加所提出的问题。
尾注:信任,但验证。此页面上的大多数答案都遵循这种方法,以查看语句 始终首先调用父类(super class)方法 是否具有逻辑支持。事实证明,它没有;至少,在类 Activity 的情况下不是这样。通常,应该通读父类(super class)的源代码以确定是否需要对父类(super class)方法的排序调用。
关于java - 在 onPause、onStop 和 onDestroy 方法中调用父类(super class)方法的正确顺序是什么?为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18821481/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer