切记:此函数只有在focus为true的时候回调一下app的方法,false的时候不会回调。所以不要通过true/false来做区别处理。
一、问题:
最近看到google原声的app中在onWindowFoucusChanged的回调中做资源回收:
代码中在hasWindowFocus的时候要回收listener。结果,显而易见,TMD出现内存泄漏了。
日了狗了,傻逼google为什么会犯这么低级的错误?
本喵觉得,可能时app的傻吊写的代码,没有及时更新?fw的逻辑变了,app还没有修改,然后google的测试没做压力测试?
好吧,只能这么解释了。
149 @Override
150 public void onWindowFocusChanged(boolean hasWindowFocus) {
151 long startTime = System.currentTimeMillis();
152 if (hasWindowFocus) {
153 Log.d(TAG, "Listening for condition changes");
154 mConditionManager.addListener(this);
155 Log.d(TAG, "conditions refreshed");
156 mConditionManager.refreshAll();
157 } else {
158 Log.d(TAG, "Stopped listening for condition changes");
159 mConditionManager.remListener(this);
160 }
161 if (DEBUG_TIMING) {
162 Log.d(TAG, "onWindowFocusChanged took "
163 + (System.currentTimeMillis() - startTime) + " ms");
164 }
165 }
二、原因
辣么,为何activity在stop的时候不会把false的状态回调给app呢?
本喵没辣么吊,没有搞懂ams,wms的这个时机,从demo及log输出还有部分wms的代码看:
先destroy的,然后触发windowFoucsChange,由于先destroy,window及view都已经移除了,madded被false,所以不会触发回调了;当activity重新创建之后,window和view被再次添加,madded为true,此时可以走到回调。
wms通过binder和handle发送处理调用到viewrootimpl的,impl收到后再通过handle发送消息来处理。
所以真正调用focuschange实在stop还是destory,我也不确定,真心看不动wms那么多的调用。总之,在stop的时候detach了把madded搞成false,后面消息来了,发现madded时false,也就不回调app了。
public void handleMessage(Message msg) {
case MSG_WINDOW_FOCUS_CHANGED: {
if (mAdded) {
mView.dispatchWindowFocusChanged(hasWindowFocus);
三、demo几log
启动app,
01-09 01:00:23.444 1731 1756 D ViewRootImpl:
womdpwFcousChanged hasFocus: false
01-09 01:00:23.510 1731 1731 D ViewRootImpl: HandleMessage
mAdded: true
01-09 01:00:23.510 1731 1731 D ViewRootImpl: HandleMessage mView: DecorView@3679ac3[Launcher], hasWindowFocus: false
01-09 01:00:23.553 3184 3184 D lstdemo : onCreate
01-09 01:00:23.566 3184 3184 I lstdemo : onStart called.
01-09 01:00:23.574 3184 3184 I lstdemo :
onResume called.
01-09 01:00:23.633 3184 3197 D ViewRootImpl:
womdpwFcousChanged hasFocus: true
01-09 01:00:23.643 3184 3184 D ViewRootImpl: HandleMessage mAdded: true
01-09 01:00:23.643 3184 3184 D ViewRootImpl: HandleMessage mView: DecorView@aa4420[MainActivity], hasWindowFocus: true
01-09 01:00:23.644 3184 3184 I l
stdemo :
onWindowFocusChanged
called. hasFocus :true
竖屏--横屏
01-09 01:00:27.153 3184 3184 I lstdemo : onPause called.
01-09 01:00:27.182 3184 3184 I lstdemo : onStop called.
01-09 01:00:27.182 3184 3184 I lstdemo :
onDestory called.
01-09 01:00:27.218 3184 3197 D ViewRootImpl:
womdpwFcousChanged hasFocus: false
01-09 01:00:27.251 3184 3184 D lstdemo : onCreate
01-09 01:00:27.253 3184 3184 I lstdemo : onStart called.
01-09 01:00:27.259 3184 3184 I lstdemo :
onResume called.
01-09 01:00:27.303 3184 3196 D ViewRootImpl:
womdpwFcousChanged hasFocus: true
01-09 01:00:27.312 3184 3184 D ViewRootImpl: HandleMessage
mAdded: false
01-09 01:00:27.314 3184 3184 D ViewRootImpl: HandleMessage
mAdded: true
01-09 01:00:27.314 3184 3184 D ViewRootImpl: HandleMessage mView: DecorView@566f550[MainActivity], hasWindowFocus: true
01-09 01:00:27.315 3184 3184 I lstdemo :
onWindowFocusChanged called. hasFocus :true
横屏--竖屏
01-09 01:00:29.487 3184 3184 I lstdemo : onPause called.
01-09 01:00:29.494 3184 3184 I lstdemo : onStop called.
01-09 01:00:29.495 3184 3184 I lstdemo :
onDestory called.
01-09 01:00:29.546 3184 3196 D ViewRootImpl:
womdpwFcousChanged hasFocus: false
01-09 01:00:29.574 3184 3184 D lstdemo : onCreate
01-09 01:00:29.579 3184 3184 I lstdemo : onStart called.
01-09 01:00:29.584 3184 3184 I lstdemo :
onResume called.
01-09 01:00:29.639 3184 3196 D ViewRootImpl:
womdpwFcousChanged hasFocus: true
01-09 01:00:29.645 3184 3184 D ViewRootImpl: HandleMessage
mAdded: false
01-09 01:00:29.649 3184 3184 D ViewRootImpl: HandleMessage
mAdded: true
01-09 01:00:29.649 3184 3184 D ViewRootImpl: HandleMessage mView: DecorView@50a5280[MainActivity], hasWindowFocus: true
01-09 01:00:29.650 3184 3184 I lstdemo :
onWindowFocusChanged called. hasFocus :true