初识onWindowFocusChanged(boolean hasFocus)
来源:互联网 发布:小学语文网络研修计划 编辑:程序博客网 时间:2024/06/05 03:08
之前对于Activity只关心它主要的生命周期函数,如onCreate()、onStart()、onResume()等,忽略了onWindowFocusChanged(boolean hasFocus)这个方法的存在。
但是在后来的学习中才逐渐了解到onResume()表示的是Activity处于运行期这样一种状态,它只是表示一种状态,而onWindowFocusChanged()则表示当前Activity获得或者失去焦点,当回调了这个方法时表示Activity是完全对用户可见的(只是可见,但是界面上还是一片黑呼呼的,有待draw..) 因此如果要统计Activity的渲染时间就可以使用这个方法作为渲染的结束时间。
在Activity生命周期中,onStart, onResume, onCreate都不是真正visible的时间点,真正的visible时间点是onWindowFocusChanged()函数被执行时。译注:从onWindowFocusChanged被执行起,用户可以与应用进行交互了,而这之前,对用户的操作需要做一点限制。
相信开发者都遇到过这样一种情况:经常会用到view的getWidth()、getHeight() 方法来获取该view的宽和高,如果是在onCreate()或者onResume()中调用返回的值经常都是0。
如果这个view的长宽很确定不为0的话,那么出现这种情况很可能是你过早的调用了这些方法,也就是说在这个view被加入到rootview之前你就调用了这些方法,返回的值自然为0。
解决这个问题的方法有很多,比如延缓调用这些获取宽高的方法,其中我觉得比较简单的一种方法就是在onWindowFocusChanged()中去获取控件View的width、height等信息(尤其适用于那种必须在Activity渲染完成后立马获取View宽高信息的情况)。
下面通过一个demo显示下Activity详细的生命周期:
布局文件activity_main.xml:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.monkey.testwindowsfocus.MainActivity"> <com.example.monkey.testwindowsfocus.CustomImageView android:layout_width="100dp" android:layout_height="100dp" android:src="@mipmap/ic_launcher" android:scaleType="centerCrop" android:id="@+id/btn_switch"/></RelativeLayout>
在布局文件中使用了一个自定义的CustomImageView,代码如下:
package com.example.monkey.testwindowsfocus;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.util.Log;import android.widget.ImageView;/** * Created by monkey on 2016/12/26. */public class CustomImageView extends ImageView{ public CustomImageView(Context context) { super(context); } public CustomImageView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Log.i(MainActivity.TAG, "onMeasure "); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); Log.i(MainActivity.TAG, "onLayout "); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.i(MainActivity.TAG, "onDraw "); }}
注:为了方便MainActivity和SecondActivity共用同一个布局文件,在MainActivty中点击CustomImageView跳转到SecondActivity。
MainActivity:
package com.example.monkey.testwindowsfocus;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;public class MainActivity extends AppCompatActivity { public static final String TAG = "TAG"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG, "MainActivity onCreate "); initView(); } private void initView() { CustomImageView ivSwitch = (CustomImageView)findViewById(R.id.btn_switch); ivSwitch.addOnLayoutChangeListener( new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) { Log.i(TAG, "MainActivity onLayoutChange "); } }); ivSwitch.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this,SecondActivity.class); startActivity(intent); } } ); } @Override public void onAttachedToWindow() { super.onAttachedToWindow(); Log.i(TAG, "MainActivity onAttachedToWindow "); } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); Log.i(TAG, "MainActivity onDetachedFromWindow "); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); Log.i(TAG, "MainActivity onWindowFocusChanged hasFocus--->"+hasFocus); } @Override protected void onStart() { super.onStart(); Log.i(TAG, "MainActivity onStart "); } @Override protected void onResume() { super.onResume(); Log.i(TAG, "MainActivity onResume "); } @Override protected void onRestart() { super.onRestart(); Log.i(TAG, "MainActivity onRestart "); } @Override protected void onPause() { super.onPause(); Log.i(TAG, "MainActivity onPause "); } @Override protected void onStop() { super.onStop(); Log.i(TAG, "MainActivity onStop "); } @Override protected void onDestroy() { super.onDestroy(); Log.i(TAG, "MainActivity onDestroy "); }}
SecondeActivity:
package com.example.monkey.testwindowsfocus;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(MainActivity.TAG, "SecondActivity onCreate "); initView(); } private void initView() { CustomImageView ivSwitch = (CustomImageView)findViewById(R.id.btn_switch); ivSwitch.addOnLayoutChangeListener( new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) { Log.i(MainActivity.TAG, "SecondActivity onLayoutChange "); } }); } @Override public void onAttachedToWindow() { super.onAttachedToWindow(); Log.i(MainActivity.TAG, "SecondActivity onAttachedToWindow "); } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); Log.i(MainActivity.TAG, "SecondActivity onDetachedFromWindow "); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); Log.i(MainActivity.TAG, "SecondActivity onWindowFocusChanged hasFocus--->"+hasFocus); } @Override protected void onStart() { super.onStart(); Log.i(MainActivity.TAG, "SecondActivity onStart "); } @Override protected void onResume() { super.onResume(); Log.i(MainActivity.TAG, "SecondActivity onResume "); } @Override protected void onRestart() { super.onRestart(); Log.i(MainActivity.TAG, "SecondActivity onRestart "); } @Override protected void onPause() { super.onPause(); Log.i(MainActivity.TAG, "SecondActivity onPause "); } @Override protected void onStop() { super.onStop(); Log.i(MainActivity.TAG, "SecondActivity onStop "); } @Override protected void onDestroy() { super.onDestroy(); Log.i(MainActivity.TAG, "SecondActivity onDestroy "); }}
点击App图标后的生命周期如下:
com.example.monkey.testwindowsfocus I/TAG: MainActivity onCreate
com.example.monkey.testwindowsfocus I/TAG: MainActivity onStart
com.example.monkey.testwindowsfocus I/TAG: MainActivity onResume
com.example.monkey.testwindowsfocus I/TAG:
MainActivity onAttachedToWindow
com.example.monkey.testwindowsfocus I/TAG: onMeasure
com.example.monkey.testwindowsfocus I/TAG: onMeasure
com.example.monkey.testwindowsfocus I/TAG: onMeasure
com.example.monkey.testwindowsfocus I/TAG: onMeasure
com.example.monkey.testwindowsfocus I/TAG: onLayout
com.example.monkey.testwindowsfocus I/TAG: MainActivity onLayoutChange
com.example.monkey.testwindowsfocus I/TAG:
MainActivity onWindowFocusChanged hasFocus—>true
com.example.monkey.testwindowsfocus I/TAG: onDraw
点击CustomImageView启动SecondActivity:
com.example.monkey.testwindowsfocus I/TAG: MainActivity onPause
com.example.monkey.testwindowsfocus I/TAG:
MainActivity onWindowFocusChanged hasFocus—>false
com.example.monkey.testwindowsfocus I/TAG: SecondActivity onCreate
com.example.monkey.testwindowsfocus I/TAG: SecondActivity onStart
com.example.monkey.testwindowsfocus I/TAG: SecondActivity onResume
com.example.monkey.testwindowsfocus I/TAG:
SecondActivity onAttachedToWindow
com.example.monkey.testwindowsfocus I/TAG: onMeasure
com.example.monkey.testwindowsfocus I/TAG: onMeasure
com.example.monkey.testwindowsfocus I/TAG: onMeasure
com.example.monkey.testwindowsfocus I/TAG: onMeasure
com.example.monkey.testwindowsfocus I/TAG: onLayout
com.example.monkey.testwindowsfocus I/TAG: SecondActivity onLayoutChange
com.example.monkey.testwindowsfocus I/TAG:
SecondActivity onWindowFocusChanged hasFocus—>true
com.example.monkey.testwindowsfocus I/TAG: onDraw
com.example.monkey.testwindowsfocus I/TAG: MainActivity onStop
在SecondActivity页面点击返回键:
com.example.monkey.testwindowsfocus I/TAG: SecondActivity onPause
com.example.monkey.testwindowsfocus I/TAG: MainActivity onRestart
com.example.monkey.testwindowsfocus I/TAG: MainActivity onStart
com.example.monkey.testwindowsfocus I/TAG: MainActivity onResume
com.example.monkey.testwindowsfocus I/TAG:
MainActivity onWindowFocusChanged hasFocus—>true
com.example.monkey.testwindowsfocus I/TAG: onDraw
com.example.monkey.testwindowsfocus I/TAG:
SecondActivity onWindowFocusChanged hasFocus—>false
com.example.monkey.testwindowsfocus I/TAG: SecondActivity onStop
com.example.monkey.testwindowsfocus I/TAG: SecondActivity onDestroy
com.example.monkey.testwindowsfocus I/TAG:
SecondActivity onDetachedFromWindow
在MainActivity页面点击返回键:
com.example.monkey.testwindowsfocus I/TAG:
MainActivity onWindowFocusChanged hasFocus—>false
com.example.monkey.testwindowsfocus I/TAG: MainActivity onPause
com.example.monkey.testwindowsfocus I/TAG: MainActivity onStop
com.example.monkey.testwindowsfocus I/TAG: MainActivity onDestroy
com.example.monkey.testwindowsfocus I/TAG:
MainActivity onDetachedFromWindow
- 初识onWindowFocusChanged(boolean hasFocus)
- 巧用onWindowFocusChanged(boolean hasFocus)
- onWindowFocusChanged(boolean hasFocus)
- android四大组件之Activity - (1)从源码中理解并巧用onWindowFocusChanged(boolean hasFocus)
- android onWindowFocusChanged(boolean hasWindowFocus)
- onWindowFocusChanged
- onWindowFocusChanged
- onWindowFocusChanged
- onWindowFocusChanged
- onWindowFocusChanged?
- onWindowFocusChanged
- onWindowFocusChanged
- onWindowFocusChanged (boolean hasWindowFocus) 一个很重要的回调函数,执行后才能获取到view的width等属性
- Boolean
- onWindowFocusChanged重要作用
- onWindowFocusChanged重要作用
- onWindowFocusChanged重要作用
- onWindowFocusChanged重要作用
- leetcode--Word Pattern
- web项目需要做好的事之一
- 练习
- 第41篇白板同步延迟问题(三)
- 迷瘴
- 初识onWindowFocusChanged(boolean hasFocus)
- 分页的总页数算法
- PostgreSQL的用户、角色和权限管理
- [LeetCode]Meeting Rooms II
- postgresql查询所有系统表,当前用户,当前时间戳
- 实用Android库-YFAndroidLibs概述
- MongoDB3.2增删查改方法简述(CRUD操作)
- js学习笔记2016.12.26
- 异步任务神器 Celery 简明笔记