完整的方法应该是
@Override
public void onWindowFocusChanged(boolean hasFocus){
}
这个方法的说明
官方文档
/**
* Called when the current {@link Window} of the activity gains or loses
* focus. This is the best indicator of whether this activity is visible
* to the user. The default implementation clears the key tracking
* state, so should always be called.
*
* <p>Note that this provides information about global focus state, which
* is managed independently of activity lifecycles. As such, while focus
* changes will generally have some relation to lifecycle changes (an
* activity that is stopped will not generally get window focus), you
* should not rely on any particular order between the callbacks here and
* those in the other lifecycle methods such as {@link #onResume}.
*
* <p>As a general rule, however, a resumed activity will have window
* focus... unless it has displayed other dialogs or popups that take
* input focus, in which case the activity itself will not have focus
* when the other windows have it. Likewise, the system may display
* system-level windows (such as the status bar notification panel or
* a system alert) which will temporarily take window input focus without
* pausing the foreground activity.
*
* @param hasFocus Whether the window of this activity has focus.
*
* @see #hasWindowFocus()
* @see #onResume
* @see View#onWindowFocusChanged(boolean)
*/
大概翻译(直接使用的百度翻译)
当活动的当前链接窗口获得或失去焦点时调用。这是用户是否可以看到此活动的最佳指示器。默认实现清除密钥跟踪状态,因此应始终调用它。请注意,这提供了有关全局焦点状态的信息,全局焦点状态是独立于活动生命周期进行管理的。因此,虽然焦点更改通常与生命周期更改有一定关系(停止的活动通常不会获得窗口焦点),但您不应依赖此处回调与其他生命周期方法(如@link onresume)回调之间的任何特定顺序。但是,作为一般规则,恢复的活动将具有窗口焦点…除非它显示了其他获得输入焦点的对话框或弹出窗口,在这种情况下,当其他窗口拥有活动时,活动本身将没有焦点。同样,系统可能会显示系统级窗口(如状态栏通知面板或系统警报),这些窗口将临时获得窗口输入焦点,而不暂停前台活动。
实际测试出来的调用时机为:
//正常打开界面
onStart -> onResume -> onWindowFocusChanged(true)
//弹窗或遮挡界面 -> 无遮挡
onWindowFocusChanged(false) -> onWindowFocusChanged(true)
//息屏 -> 亮屏
onPause -> onStop -> onWindowFocusChanged(false) -> onStart -> onResume -> onWindowFocusChanged(true)
//跳转界面,原界面为Main,跳转的测试界面为Test
Main onPause -> Test onStart -> Test onResume -> Main onWindowFocusChanged(false) -> Test onWindowFocusChanged(true) -> Main onStop
//结束(finish)界面
Test onPause -> Main onStart -> Main onResume -> Test onWindowFocusChanged(false) -> Main onWindowFocusChanged(true) -> Test onStop -> Test onDestroy
测试截图,测试机型:荣耀V10
跳转界面:
结束界面
总结:
onWindowFocusChanged(true)这个方法实际测试效果为在onResume执行之后调用的,可以拿到控件参数(宽高)信息(在onResume里拿到的不准),也可以用于同步服务器数据,注意,在onResume之后调用并不等于onResume之后就一定获得焦点,存在键盘、弹窗等遮挡屏幕的情况会获得焦点,但Activity仍然正常执行,之前看其他博客说结束界面时,在onWindowsFocusChanged(false)里执行释放资源会导致内存泄漏,原因时onWindowFocusChanged会执行在onDestroy之后,虽然实际测试在onStop之前就执行了,不过还是建议不要在这个回调里执行释放资源,因为执行的顺序与生命周期无关,只与全局焦点变动有关。