切記:此函數只有在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 lstdemo : 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