網站首頁 編程語言 正文
在android 11的 InputMethodManager的源碼中,查看 windowDismissed(),如下
/**
* An empty method only to avoid crashes of apps that call this method via reflection and do not
* handle {@link NoSuchMethodException} in a graceful manner.
*
* @deprecated This is an empty method. No framework method must call this method.
* @hide
*/
public void windowDismissed(IBinder appWindowToken) {
// Intentionally empty.
//
// It seems that some applications call this method via reflection to null clear the
// following fields that used to exist in InputMethodManager:
// * InputMethodManager#mCurRootView
// * InputMethodManager#mServedView
// * InputMethodManager#mNextServedView
// so that these objects can be garbage-collected when an Activity gets dismissed.
//
// It is indeed true that older versions of InputMethodManager had issues that prevented
// these fields from being null-cleared when it should have been, but the understanding of
// the engineering team is that all known issues have already been fixed as of Android 10.
//
// For older devices, developers can work around the object leaks by using
// androidx.activity.ComponentActivity.
// See https://issuetracker.google.com/u/1/issues/37122102 for details.
//
// If you believe InputMethodManager is leaking objects in API 24 or any later version,
// please file a bug at https://issuetracker.google.com/issues/new?component=192705.
}
/*
* 以下三個字段,在低于 android 10 的版本中是都存在的;之后,有變更。
* 低于 android 10,當Activity dismissed 時,可以通過反射,將它們置null,使它們不再持有該Activity中View的引用,防止內存泄露。
* InputMethodManager#mCurRootView
* InputMethodManager#mServedView
* InputMethodManager#mNextServedView
*
* android 10之后修復了所有已知問題。
* 對于較老的版本,建議使用 androidx.activity.ComponentActivity 及其子類。
* issues/37122102,說明 android N/7.0 (api 24),就開始了修復。
*
* android 11 source code:http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java
* android 10 source code:http://aospxref.com/android-10.0.0_r47/xref/frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java
*/
解決方案:對于低于android10,且非 ComponentActivity
的context,反射獲取InputMethodManager
對象中的 mCurRootView
、mServedView
、mNextServedView
這三個屬性,轉換為View類型后,判斷view的context等于要釋放的Activity的context時,將這個屬性置為null。
fun fixMemoryLeak(context: Context?) {
try {
context ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) return // android 10 已修復
if (context is ComponentActivity) return // androidx.activity.ComponentActivity 已修復
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager ?: return
imm.javaClass.declaredFields.filter {
it.name == "mCurRootView" || it.name == "mServedView" || it.name == "mNextServedView"
}.forEach { filed ->
val origin = filed.isAccessible
if (!origin) {
filed.isAccessible = true
}
(filed.get(imm) as? View)?.takeIf { it.context == context }?.also {
filed.set(imm, null)
}
filed.isAccessible = origin
}
} catch (e: Exception) {
e.printStackTrace()
}
}
原文鏈接:https://blog.csdn.net/jjwwmlp456/article/details/124580048
相關推薦
- 2022-01-06 react實現todolist的增刪改查
- 2022-09-19 C++四種cast使用詳細介紹_C 語言
- 2023-01-10 Flutter圖片緩存管理ImageCache原理分析_Android
- 2022-08-18 C/C++?extern和static的使用詳解_C 語言
- 2022-04-17 iOS喚起記住密碼的數字鍵盤,輸入的時候發生閃爍的問題
- 2024-03-24 go 連接redis集群
- 2022-09-05 Redis的數據刪除策略
- 2022-04-19 開發中為什么用translate來改變位置而不是定位?
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支