view的context一定是Activity吗
创始人
2024-01-30 00:43:55
0

最近在使用glide加载图片的时候出现“Caused by: java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity”,但明明在使用glide之前已经进行了Activity是否destroy的判断,为什么还会发生这个crash呢?注意到Android版本为4.4.2,对应crash中glide使用的context为view.getContext(),所以是不是因为view.getContext()不是Activity类型,所以没有走到判断逻辑,debug发现此时的view.getContext()为TintContextWrapper类型,这是为什么呢?

源码分析

我的view继承android.support.v7.widget包下的AppCompatImageView,查看AppCompatImageView源码如下:
在这里插入图片描述
可以看到在AppcompatImageView中的super方法中对于原本传入的context进行了封装也就是TintContextWrapper.wrap(context),查看TintContextWrapper.wrap(context)方法源码如下:

public class TintContextWrapper extends ContextWrapper {private static final Object CACHE_LOCK = new Object();private static ArrayList> sCache;private final Resources mResources;private final Theme mTheme;public static Context wrap(@NonNull Context context) {if (shouldWrap(context)) {synchronized(CACHE_LOCK) {if (sCache == null) {sCache = new ArrayList();} else {int i;WeakReference ref;for(i = sCache.size() - 1; i >= 0; --i) {ref = (WeakReference)sCache.get(i);if (ref == null || ref.get() == null) {sCache.remove(i);}}for(i = sCache.size() - 1; i >= 0; --i) {ref = (WeakReference)sCache.get(i);TintContextWrapper wrapper = ref != null ? (TintContextWrapper)ref.get() : null;// 将context赋值给了baseContextif (wrapper != null && wrapper.getBaseContext() == context) {return wrapper;}}}TintContextWrapper wrapper = new TintContextWrapper(context);sCache.add(new WeakReference(wrapper));return wrapper;}} else {return context;}}// 判断是否封装contextprivate static boolean shouldWrap(@NonNull Context context) {if (!(context instanceof TintContextWrapper) && !(context.getResources() instanceof TintResources) && !(context.getResources() instanceof VectorEnabledTintResources)) {return VERSION.SDK_INT < 21 || VectorEnabledTintResources.shouldBeUsed();} else {return false;}}
}

可以看出来TintContextWrapper继承ContextWrapper。在wrap方法中根据shouldWrap(context)进行判断。
(1)shouldWrap(context)为false,直接返回外部传入的context,未进行封装。
(2)shouldWrap(context)为true,将外部传入的context赋值给TintContextWrapper的baseContext,封装成TintContextWrapper。
查看
shouldWrap
方法,VERSION.SDK_INT < 21(Android5.0)时会返回true,封装context。

总结:对于view的context,android5.0以下,使用v7包下的view,对应的view的context为TintContextWrapper类型,其余时为activity类型。

view的context获取Activity

从上面得知,view的context不一定是Activity,那我们怎么从view的context得到对应的Activity呢?
方法如下:

private fun getActivityFromView(viewContext: Context): Activity? {var context = viewContextwhile (context is ContextWrapper) {if (context is Activity) {return context}context = context.baseContext}return null
}

参考

https://blog.csdn.net/yyanjun/article/details/79896677
https://www.jianshu.com/p/448c578a252b

相关内容

热门资讯

盘点当下最赚钱的无本创业小项目... 创业可以说是现在非常受欢迎的话题,很多人都会想要去创业,去实现自己的梦想,或者说是想改变一下自己的生...
适合小区创业的小本项目有哪些 ... 适合小区创业的小本项目有哪些?创业是每个人都想干的一件事,但是又不知到从何做起,大型的加盟项目投资费...
小区里的小本暴利项目哪些 有哪... 受到疫情影响,今年从年初开始,经济大环境就不算好。大家都在抱怨现在挣钱太难了,市场不景气,都没什么生...
千元小本创业有哪些 2018年... 经济形势的发展下,人民币逐渐贬值。对于创业者来说,想要找到1000元以下创业项目是比较困难的。因为一...
适合小本创业的五个好项目 推荐... 二胎政策开放很久了,儿童行业是具有潜力的市场,现在的家长都很疼爱自己的孩子,很注重孩子的早期教育培训...
2020年最好的创业项目是什么...   还不知道朋友看这里那今天我们就来说几个创业的好项目给大家分享:1、开宠物店,现在的年轻人压力大,...
小本创业代理好项目 小本创业代...  短视频,自媒体,达人种草一站服务最新移动电商创业项目:手机微信制作平台照片书照片书就是把您手机里的...
在四五线小城市有哪些城镇小本创... 如今的生活越来越好,每个人对美好生活的留念越来越重视了,很多人在生活中不管遇到什么样的事情,只要是值...
2019小本创业项目哪个比较好... 现在这些传统行业竞争压力大,投入成本也越来越高了。想要创业但是条件又有限,怎样才能以最小的成本去努力...
投入一千多 有必要理财吗 投入... 摘要:项目:防晒帽子、配饰作为一个赚女人钱的项目,卖防晒帽及配饰还是很不错的。有多少女性朋友,惧怕炎...