技术标签: OnDestroy Android基础 源码分析 Activity的几种关闭方式 Finish和OnBackPressed Android
开发的过程中,常常见到finish()和onBackPressed()以及ondestory好像都能关掉Activity。自己抽空总结一下,首先看源码,源码基于'androidx.appcompat:appcompat:1.1.0'来分析。
android.app.Activity中源码:
@Override
public void finish() {
//关闭activity但不关闭栈
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
public void finishAndRemoveTask() {
//如果当前activity是处于栈底,则关闭activity的同时关闭栈
finish(FINISH_TASK_WITH_ROOT_ACTIVITY);
}
/**
* 完成当前活动并指定是否删除与此活动关联的任务。
*/
private void finish(int finishTask) {
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (resultData != null) {
// 准备此{@link Intent}以退出应用程序进程。
resultData.prepareToLeaveProcess(this);
}
// 1、猜测更具finish的类别finishTask进行关闭
// 退回上一个Activity,并且会将resultCode, resultData返回。如果启动的是startActivityForResult将会在onActivityResult响应
if (ActivityManager.getService().finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {//如果有嵌套的父级Activity,则在父级activity关闭,此时childActivity会被自动销毁。
mParent.finishFromChild(this);
}
//如果Intent中带有要保存UI信息,则应该保存mInten中的信息
if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_RESTORE, mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
}
}
androidx.appcompat.app.AppCompatActivity中的源码
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
androidx.fragment.app.FragmentActivity中的源码
@Override
protected void onDestroy() {
super.onDestroy();
//关闭可能包含的Fragment
mFragments.dispatchDestroy();
//让Lifecycle处于destory状态
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
android.app.Activity中的源码
/**
* 1、在销毁活动之前执行任何最后的清理。可以是人为调用了finish,或者系统内存紧张调用了。
* 2、不能在destory中保存数据,因为系统将简单地杀死活动的托管过程,即可能关闭程序ondestory不一定被调用了
* 3、子类必须调用super.onDestory
*/
@CallSuper
protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;
/**
* 关闭当前Activity管理的所有dialog,所以diaolog 不应该使用applicationContext
*/
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}
// 关闭任何Cursors,所以cursor不应该用ApplicationContext初始化
// 现在的版本比以前的低版本对内存泄漏的检测和解决更加强大了
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}
//关闭任何 searchDialog
if (mSearchManager != null) {
mSearchManager.stopSearch();
}
//关闭ActionBar
if (mActionBar != null) {
mActionBar.onDestroy();
}
//ActivityLifecycleCallbacks 取消生命周期回调监听
getApplication().dispatchActivityDestroyed(this);
}
androidx.activity.ComponentActivity中的源码
public void onBackPressed() {
mOnBackPressedDispatcher.onBackPressed();
}
androidx.activity.OnBackPressedDispatcher中的源码
/**
* 1、只有最后按得back返回键,才能将OnBackPressedCallback 设置为isEnabled=true
* 2、旧版的OnbackPressed好分析一些
* 3、随着版本的更新,软件内部的代码结构和构造是不断变化的
*/
@MainThread
public void onBackPressed() {
Iterator<OnBackPressedCallback> iterator =
mOnBackPressedCallbacks.descendingIterator();
while (iterator.hasNext()) {
OnBackPressedCallback callback = iterator.next();
if (callback.isEnabled()) {
callback.handleOnBackPressed();
return;
}
}
if (mFallbackOnBackPressed != null) {
mFallbackOnBackPressed.run();
}
}
总结:
1、调用onBackPressed()方法不一定就能结束Activity。
2、调用onBackPressed()方法结束Activity,其调用的终究还是finish()方法。
3、finish()方法最后调用了Ondestory。
4、Android系统内存紧张时,可能会关闭软件进程,此时Activity的该方法不一定必然被调用。
安装golang(Linux环境)# 下载linux源码包中文官网地址https://studygolang.com/dl# 下载命令直接下载wget https://studygolang.com/dl/golang/go1.17.2.linux-amd64.tar.gz# 解压到指定目录tar -zxf go1.17.2.linux-amd64.tar.gz -C /usr/local# 配置go的相关路径,在末尾加入以下内容vim ~/.bashrc# 设置go语言路径exp..
来自图解面试算法。这道题的主要思路是深度优先搜索。每次走到一个是1的格子,就搜索整个岛屿,并计算当前岛屿的面积。最后返回岛屿面积的最大值。网格可以看成是一个无向图的结构,每个格子和它上下左右四个格子相邻。如果四个相邻的格子坐标合法,就可以继续搜索。在深度优先搜索的时候要注意避免重复遍历。我们可以把已经遍历过的陆地改成2,这样遇到2我们就知道已经遍历过这个格子了,不进行重复遍历。class Solution { public int maxAreaOfIsland(int[][] gri...
请关注“知了堂学习社区”,地址:http://www.zhiliaotang.com/portal.php1.Ajax作用ajax是什么 传统web应用采用同步交互方式实现数据呈现,当服务器处理请求时,客户端必须要等待ajax建立起了浏览器客户端与服务器之间的桥梁,可以消除网络交互过程中对的处理-等待-处理的缺陷ajax全称:Asynchronous JavaScript and XML 异
大家好,我是单片机爱好者-MCU起航。这里说下使用库函数方式控制STM8S103F3P6实现片上EEPROM读写操作。很多人接触EEPROM,都是从24C01或者24C02开始。因为早期的单片机资源比较匮乏,所以需要外接这些东西。但随着单片机的片上资源越来越丰富,在某些情况下,这些外接的EEPROM其实是可以省掉的。相当一部分的单片机内部集成了一部分EEPROM,还有的单片机,内部虽然没有EEPR...
1、更新时间 $ ntpdate time-a.nist.gov2、查看日志 date Wed Dec 3 00:20:06 EST 2008 这个时间是不对的,明显时区错误“EST”,这时你需要这么做: $ cp /usr/share/zoneinfo/Asia/shanghai /etc/localtime 这就是把该时区文件覆
I2C????: I2C(inter-integrated Circuit)????Phiilps?????,???????,??????,?????(??USART,CAN???????),??????????????????(IC)?????. (??I2C????,?????I2C?????????) ???: 1,????????,?????????(SDA)
又一次挂了,简直无语。一二题A了,然后就卡在第三题。第三题思路我很快就想出来了,然后就卡在实现上面了,我居然用了高精度,本来模乘法也可以过得;奇怪的是我的前几个点都过了,后面几个全部暴栈,至今没有找出原因,可能是求答案的时候写丑了之后就一直想第四题,一道只有几百B的神代码- -,几乎用完的所有的时间,结果还是没有想出来!然后第五题我想出来dp,自认为可以过几个点,结果没有时间调试了,然
常见场景:点击列表详情,跳转到详情内页,传递id参数获取详情数据。我们先来看看路由跳转的几种方式:1、通过params方式传参通过$route.push的path携带参数方式(路由配置中指定参数)// 路由配置{ path: '/detail/:id', //若id后面加?代表这个参数是可选的,即使不传id也不会导致页面无法访问 name: 'detail', component: Detail }// 列表中跳转this.$router.push({
→题目链接←一看到题就可以想到是动态规划首先不作任何优化的dp时间复杂度显然是n^3的dp[i][j]表示第i棵树,高度为j时最多可以吃到多少个柿子num[i][j]表示第i棵树,高度为j的位置上有几个柿子显然dp[i][j]=max(dp[i][j+1]+num[i][j] , dp[1~n][j+delta]+num[i][j])但是n^3是过不了的我们发现
基于安卓开发的QQ登陆页面,实现登陆注册内容(一)QQ登陆注册首先对于QQ登陆注册而言,先控制好布局,和对控件的使用;页面效果如下:部分代码:<TextView android:layout_width="match_parent" android:layout_height="67dp" android:layout_marginTop="50dp"...
1.确定软件版本将项目切换到Project,打开app目录下的build.gradle文件versionCode是app的大版本好,为数值类型,默认为1,改成2versionName是app的具体版本号,为际符串类型,默认为1.0,改成2.02.指定生成的APK文件名还是在刚刚的bulid.gradle文件中修改,默认生成release版apk名为app-release.apk在android内部修改自己的apk名3.生成自己密钥签名的realease版apk直接点Build APK(s
外观模式外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。#ifndef _FACADE_H_#define _FACADE_H_#include//子系统1class subSystemOne{public: void subMet