大框架不错,细节毛病多_Android开发精要书评-查字典图书网
查字典图书网
当前位置: 查字典 > 图书网 > 互联网 > Android开发精要 > 大框架不错,细节毛病多
Allenz Android开发精要 的书评 发表时间:2015-01-09 14:01:48

大框架不错,细节毛病多

基本上安卓开发大部分要用到的基础点都介绍了,而且涉及了一些原理和较深入的内容,没有停留在泛泛而谈Api文档,这点是比较好的。
但是内容细节的准确性有不少瑕疵,比如110~111页讲解Activity生命周期,以及提到在Activty.onPause中检查Activity.onSaveInstanceState是否被调用的“小技巧”,作者不明确地指出Activity.onSaveInstanceState回调发生在Activity.onPause回调之前。但安卓官方文档明确指出Activity.onSaveInstanceState回调发生在Activity.onStop回调之前,而和Activity.onPause调用的先后顺序是不确定的
(原文:“If called, this method will occur before onStop(). There are no guarantees about whether it will occur before or after onPause().”
链接:http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState%28android.os.Bundle%29)
,这个说明也和实际测试是一致的。
这让人很怀疑此书里头的代码是否作者都亲自试过了,还是部分来自于想当然。

展开全文


推荐文章

猜你喜欢

附近的人在看

推荐阅读

拓展阅读

对“大框架不错,细节毛病多”的回应

飘飘白云 2015-03-13 09:26:08

楼主看得很仔细。作者在这里确实是不准确的,他只看到一处地方的源码而没有看全部源码。

我贴上4.2.2版本的源码放这里就清楚了:

总共三处地方调用了onSaveInstanceState:
/Android4_2_2/android/frameworks/base/core/java/android/app/ActivityThread.java:
2999 state = new Bundle();
3000 state.setAllowFds(false);
3001: mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3002 r.state = state;
3003 }
....
3131 state = new Bundle();
3132 state.setAllowFds(false);
3133: mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3134 r.state = state;
3135 } else {
....
3668 r.state = new Bundle();
3669 r.state.setAllowFds(false);
3670: mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
3671 }

在 pause 处理中:
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState) {
// Next have the activity save its current state and managed dialogs...
if (!r.activity.mFinished && saveState) {
state = new Bundle();
state.setAllowFds(false);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
r.state = state;
}
// Now we are idle.
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName());
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
}

在 stop 处理中:
private void performStopActivityInner(ActivityClientRecord r,
StopInfo info, boolean keepShown, boolean saveState) {
// Next have the activity save its current state and managed dialogs...
if (!r.activity.mFinished && saveState) {
if (r.state == null) {
state = new Bundle();
state.setAllowFds(false);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
r.state = state;
} else {
state = r.state;
}
}

if (!keepShown) {
try {
// Now we are idle.
r.activity.performStop();
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to stop activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
r.stopped = true;
}

r.paused = true;
}

还有一处是在 relaunch 处理中:
private void handleRelaunchActivity(ActivityClientRecord tmp) {
// Need to ensure state is saved.
if (!r.paused) {
performPauseActivity(r.token, false, r.isPreHoneycomb());
}
if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
r.state = new Bundle();
r.state.setAllowFds(false);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}

handleDestroyActivity(r.token, false, configChanges, true);

r.startsNotResumed = tmp.startsNotResumed;

handleLaunchActivity(r, currentIntent);
}