Android onWindowFocusChanged() 配合 WeakReference 弱引用解决页面间跳转不连贯问题
小菜最近在处理适配方面的问题,今天发现在一些低版本且性能不佳的手机上,冷启动过程中,从 SplashActivity 到 MainActivity 过程中,主页面还没有加载完,启动页先销毁回到手机主页面,过1-2s才进入 MainActivity,中间的间隔时间比较长,用户体验较差。
小菜调试了很久,通过【弱引用 + onWindowFocusChanged】的方式来解决目前的问题,也许不是最好的处理方式,但小菜觉得是相对简单的方式,因此记录一下。
问题原因
小菜的 MainActivity 中需要处理很多业务逻辑以及配置项处理等,在 UI 页面展示前会相对较慢,因此导致前一个 SplashActivity 页面已经销毁但是后一个主 MainActivity 还没有加载出来,导致一个较长的时间间隔。
技术方向
WeakReference 弱引用
弱引用,即在引用对象的同时仍然允许通过垃圾回收来回收该对象。Android 中常用来在非 UI 线程处理图片和 Handler 与 Activity 的交互等。
onWindowFocusChanged() 周期函数
判断窗口变化,在当前 Activity 的窗口获取焦点或失去焦点时进行回调。
解决方式
- 在第一个页面中添加弱引用,并且在页面跳转过程中不直接 finish 掉本页面;
public class SplashActivity extends AppCompatActivity { private Button mButton; private static WeakReference<AppCompatActivity> mWeakReference; public static void finishActivity() { if (mWeakReference != null && mWeakReference.get() != null) { mWeakReference.get().finish(); } } @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_splash); mWeakReference = new WeakReference<>((AppCompatActivity) this); mButton = (Button) this.findViewById(R.id.test_btn); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(SplashActivity.this, TestActivity.class)); } }); } }
- 在第二个页面中,添加 onWindowFocusChanged() 回调判断,若是第一次进入本页面时,将上一个页面手动 finish 掉,以衔接两个页面,取消时间间隔;
public class TestActivity extends AppCompatActivity { private static final String TAG = "TestActivity"; private boolean isFirstInWindowFocusChanged = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); Loger.e("==onWindowFocusChanged==",TAG + hasFocus); if(hasFocus) { if(isFirstInWindowFocusChanged){ isFirstInWindowFocusChanged = false; SplashActivity.finishActivity(); } } } }
至此,页面跳转过程中出现短时间时间间隔问题已解决,测试正常。
扩展测试
为什么要在 onWindowFocusChanged() 方法中添加是否是首次进入本页面的状态判断?
这个主要是由 Activity 的生命周期决定的,该方法主要是监测窗口是否获取或失去焦点,测试如下:
- 首次进入该页面,生命周期执行顺序:onCreate() -> onStart() -> onResume() -> onWindowFocusChanged()
- 点击 home 键,退到后台执行顺序:onPause() ->onWindowFocusChanged() -> onStop()
- 从后台返回当前页面,生命周期执行顺序:onRestart() -> onStart() -> onResume() -> onWindowFocusChanged()
- 退出该页面,生命周期执行顺序:onPause() ->onWindowFocusChanged() -> onStop() -> onDestroy()
以下是小菜公众号,欢迎闲来吐槽~

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Android设置状态栏为白底黑字
在开发过程中可能会有将状态栏设置成白底黑字的样式,但是Android系统只有在4.4之上才可以修改状态栏颜色,想要设置状态栏为黑字,只有在Android6.0以上系统或者小米的MIUI V6以上版本或者,魅族的Flyme4.0以上版本才可以设置。 Android6.0以上设置状态栏白底黑字 首先需要通过修改colors.xml文件中的colorPrimaryDark来将状态栏背景设为白色 <?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#fff</color> <color name="colorAccent">#FF4081</color> </resources> 然后在Activity中添加代码 @Override protected void onCreate(Bundle...
- 下一篇
手把手教你使用Android studio生成正式签名的APK文件
首先,成功编译和运行程序: 项目code 运行效果图 点击Android studio 右侧工具栏的Gradle → 项目名 → :app → Tasks →android, 双击signingReport: 结果如图所示: 也就是说,我们所有通过Android studio来运行的程序都是使用了这个debug.keystore文件来进行签名的: 不过这仅仅适用于开发阶段而已,现在如果是要发布app,便需使用一个正式的keystore文件来进行签名才行。 使用Android studio生成正式签名的APK文件: 点击Android studio导航栏上的Build → Generate Signed APK,首次点击可能会提示我们输入操作系统的密码, 输入密码后点击OK,随后弹出如下图所示的创建签名APK对话框: 由于我们还没有一个正式的keystore文件,所以应该点击Create new 按钮,然后会弹出一个新的对话框来让我们填写创建keystore文件所必要的信息。根据自己的实际情况进行填写就行了: 其中: 1.第一行这里,点击这个按钮之后: 会弹出一个框,这里需要选择好路径,...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS关闭SELinux安全模块
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS8编译安装MySQL8.0.19