浅析onWindowsFocusChanged()方法
来源:互联网 发布:n卡优化 编辑:程序博客网 时间:2024/06/16 05:15
前言
在接手的项目中,看到了onWindowsFocusChanged()的方法,抽空了解下它的用途
内容
概述
从字面上来讲,onWindowsFocusChanged()方法是指当窗口焦点变化的时候;从意义来说,onWindowsFocusChanged()就是指当前的Activity的Windows(窗口)获取或者失去焦点时这个方法就会被调用,并且当回调这个方法时,Activity是完全可见的。
在Activity生命周期中,onStart(), onResume(), onCreate()都不是布局visible的时间点,真正的visible时间点是onWindowFocusChanged()函数被执行时。从onWindowFocusChanged()被执行起,用户可以与应用进行交互了,换句话说,如果你想要在Activity加载后做些操作,可以在这个方法里调用而这之前,对用户的操作需要做一点限制。
onWindowFocusChanged()的使用情景与作用
根据介绍可以了解,onWindowFocusChanged()使用于以下等情景:
首次进入一个Activity后会在onResume()方法后面调用;
从Activity 跳到另一个Activity,新的窗口会获取焦点, 就的Activity的窗口会失去焦点;
打开软键盘进行输入时,窗口失去焦点;
软键盘输入完毕消失时,窗口重新获取焦点;
应用进入后台,窗口失去焦点;
应用从后台返回当前, 窗口重新获取焦点;
…
因此其可以有如下作用:
监控一个Activity是否载完毕;
在Activity加载后进行一些操作,如获取手机屏幕的高度和宽度;
当Activity挂起或恢复时,可以在方法内进行一些数据的保存或恢复的操作;
…
onWindowFocusChanged()调用详解
介绍完onWindowFocusChanged()基本的使用情景以及作用后,撸个demo来看下onWindowFocusChanged()具体的调用情况。
首先在Activity中重写的onWindowFocusChanged()方法如下:
/** * 添加窗体在视图初始化完成过后 * * @param hasFocus */ @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { //add Window..... } }
其中参数hasFocus表示窗口是否获取或失去焦点,true表示获取焦点,false表示失去焦点。
然后我们看下总体的代码:
public class WindosFoucesDemo extends AppCompatActivity { private static final String TAG = "LifeCycleDemo"; //Activity创建时被调用 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "onCreate is called."); setContentView(R.layout.activity_main); } //Activity创建或者从后台重新回到前台时被调用 @Override protected void onStart() { super.onStart(); Log.i(TAG, "onStart is called."); } //Activity创建或者从被覆盖、后台重新回到前台时被调用 @Override protected void onResume() { super.onResume(); Log.i(TAG, "onResume is called."); } //Activity窗口获得或失去焦点时被调用,在onResume之后或onPause之后 @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if(hasFocus){ Log.i(TAG, "onWindowFocusChanged is called and" + "hasFocus is true"); }else { Log.i(TAG, "onWindowFocusChanged is called and" + "hasFocus is false"); } } //Activity被覆盖到下面或者锁屏时被调用 @Override protected void onPause() { super.onPause(); Log.i(TAG, "onPause is called."); //有可能在执行完onPause或onStop后,系统资源紧张将Activity杀死,所以有必要在此保存持久数据 } //退出当前Activity或者跳转到新Activity时被调用 @Override protected void onStop() { super.onStop(); Log.i(TAG, "onStop is called."); } //退出当前Activity时被调用,调用之后Activity就结束了 @Override protected void onDestroy() { super.onDestroy(); Log.i(TAG, "onDestory is called."); } //Activity从后台重新回到前台时被调用 @Override protected void onRestart() { super.onRestart(); Log.i(TAG, "onRestart called."); }}
运行该Demo,查看Log日志,可以得到以下日志结果。
1. 启动Activity时:
2. 按下任务栏键,Activity被遮挡时:
注意:按锁屏键和按任务栏或者Home键的生命周期是不同的,按Home执行onPause –> onStop –> onRestart –> onStart —> onResume 按锁屏键和对话框覆盖界面的生命周期是一样的,都只会进行onPause --> onResume .不会执行onStop,onRestart,onStart。
3. Activity恢复到前台时:
4. Activity退出时:
从上面的例子以及结果可以清楚的onWindowFocusChanged()在整个Activity生命周期内的调用情况,可以根据这些结果,在开发中来充分利用onWindowFocusChanged()方法的作用。
onWindowFocusChanged()源码分析
通过Activity源码去查看,发现onWindowFocusChanged()这个方法出现在WindowCallbackWrapper.java和View.java这两个类中,而WindowCallbackWrapper.java中其实也是调用View.java中的onWindowFocusChanged(),其代码如下:
/** * Called when the window containing this view gains or loses focus. Note * that this is separate from view focus: to receive key events, both * your view and its window must have focus. If a window is displayed * on top of yours that takes input focus, then your own window will lose * focus but the view focus will remain unchanged. * * @param hasWindowFocus True if the window containing this view now has * focus, false otherwise. * 当前的window(窗口)获取或者失去焦点的时候会回调这个方法.请注意,这个焦点和 * view焦点是分离的,为了获取按键事件,view和view所在的窗口都必须获得焦点.如果 * 一个窗口处于你的输入事件的最上层,那么该窗口将失去焦点而view的焦点会保持不 * 变. */ public void onWindowFocusChanged(boolean hasWindowFocus) { //获取软键盘a system window such as the keyguard may InputMethodManager imm = InputMethodManager.peekInstance(); if (!hasWindowFocus) { if (isPressed()) { //键盘有按下事件,则强制将该view包含的所有子控件全部setPressed()设置为false setPressed(false); } if (imm != null && (mPrivateFlags & FOCUSED) != 0) { //这是一个隐藏的方法(带@hide标签),当view失去焦点时会调用该方法 imm.focusOut(this); } //移onWindowFocusChanged(boolean hasFocus) 被回调的触发时机是窗口获取或失去焦点的时候.除长按事件回调的接口方法 removeLongPressCallback(); //移除轻触探测器,源码中叫 "Remove the tap detection timer." removeTapCallback(); //当焦点(fucos)从按下变成取消的时候会调用,属于隐藏方法 onFocusLost(); } else if (imm != null && (mPrivateFlags & FOCUSED) != 0) { //当view获得焦点时调用该方法,属于隐藏方法 imm.focusIn(this); } //强制view刷新drawable state,并且会回调drawableStateChanged()方法 refreshDrawableState(); }
从源码可以验证出,onWindowFocusChanged()方法被回调的触发时机是窗口获取或失去焦点的时候。并且在onResume()方法中的官方解释 Use {@link #onWindowFocusChanged} to know for certain that your activity is visible to the user (for example, to resume a game). 可以知道onWindowFocusChanged()第一次调用是在onResume()方法后面。
- 浅析onWindowsFocusChanged()方法
- view viewgroup onWindowsFocusChanged
- 浅析电脑病毒清除方法
- 默认构造方法浅析
- hashcode方法浅析
- CString方法浅析
- 浅析iOS界面设计方法
- 浅析iOS界面设计方法
- js call方法浅析
- 浅析C#扩展方法
- http的方法浅析
- boost::bind 方法浅析
- 可视化设计方法浅析
- UIApplicationDelegate-委托方法浅析
- 浅析iOS界面设计方法
- hashcode方法浅析
- hashcode方法浅析
- 浅析构造方法
- Django---orm多表操作
- Java开发中三种常用集合
- git学习(3)_标签
- 动态生成图片
- #4JavaScript图形库
- 浅析onWindowsFocusChanged()方法
- Inception
- Django---orm单表操作
- Ubuntu下安装搜狗输入法
- Professional JS(5.5.5-function properties and methods&&5.6primitive wrapper type)
- Python零基础笔记
- 水题 第二站 Tian Ji -- The Horse Racing
- linux-centos-pxe批量安装
- #6图片库改进