面试官:关于Glide常问的几个问题你掌握多少?答对了直接绿卡!(2)

return null;

}

EngineJob engineJob =

engineJobFactory.build(

key,

isMemoryCacheable,

useUnlimitedSourceExecutorPool,

useAnimationPool,

onlyRetrieveFromCache);

jobs.put(key, engineJob);

engineJob.addCallback(cb);

//开启线程池,加载图片

engineJob.start(decodeJob);

}

从上可知,Glide加载过程中使用loadFromActiveResources方法和loadFromCache方法来获取内存缓存的。

大致总结一下:

首先从弱引用读取缓存,没有的话通过Lru读取,有则取,并且加到弱引用中,如果没有会开启EngineJob进行后面的图片加载逻辑。

下面直接看之后的缓存部分代码:

  • Engine#onEngineJobComplete()

public void onEngineJobComplete(EngineJob<?> engineJob, Key key, EngineResource<?> resource) {

Util.assertMainThread();

// A null resource indicates that the load failed, usually due to an exception.

if (resource != null) {

resource.setResourceListener(key, this);

if (resource.isCacheable()) {

activeResources.activate(key, resource);

}

}

jobs.removeIfCurrent(key, engineJob);

}

void activate(Key key, EngineResource<?> resource) {

ResourceWeakReference toPut =

new ResourceWeakReference(

key,

resource,

getReferenceQueue(),

isActiveResourceRetentionAllowed);

ResourceWeakReference removed = activeEngineResources.put(key, toPut);

if (removed != null) {

removed.reset();

}

}

这里可以看到activeResources.activate(key, resource)把EngineResource放到了弱引用中,至于lru的放置逻辑如下:

  • EngineResource#release()

void release() {

if (acquired <= 0) {

throw new IllegalStateException(“Cannot release a recycled or not yet acquired resource”);

}

if (!Looper.getMainLooper().equals(Looper.myLooper())) {

throw new IllegalThreadStateException(“Must call release on the main thread”);

}

if (–acquired == 0) {

listener.onResourceReleased(key, this);

}

}

当acquired变量大于0的时候,说明图片正在使用中,也就应该放到activeResources弱引用缓存当中。而经过release()之后,如果acquired变量等于0了,说明图片已经不再被使用了,那么此时会调用listener的onResourceReleased()方法来释放资源。

  • Engine#onResourceReleased()

@Override

public void onResourceReleased(Key cacheKey, EngineResource<?> resource) {

Util.assertMainThread();

activeResources.deactivate(cacheKey);

if (resource.isCacheable()) {

cache.put(cacheKey, resource);

} else {

resourceRecycler.recycle(resource);

}

}

这里首先会将缓存图片从activeResources中移除,然后再将它put到LruResourceCache当中。这样也就实现了正在使用中的图片使用弱引用来进行缓存,不在使用中的图片使用LruCache来进行缓存的功能。

接下来就是Glide的磁盘缓存,磁盘缓存简单来说就是根据Key去DiskCache中取缓存,有兴趣可以自行看一下源码。

面试官2:为什么选择Glide不选择其他的图片加载框架?

  • Glide和Picasso

前者要更加省内存,可以按需加载图片,默认为ARGB_565,后者为ARGB_8888。

前者支持Gif,后者并不支持。

  • Glide和Fresco

Fresco低版本有优势,占用部分native内存,但是高版本一样是java内存。

Fresco加载对图片大小有限制,Glide基本没有。

Fresco推荐使用SimpleDraweeView,涉及到布局文件,这就不得不考虑迁移的成本。

Fresco有很多native的实现,想改源码成本要大的多。

Glide提供对中TransFormation帮助处理图片,Fresco并没有。

Glide版本迭代相对较快。

Glide的几个显著的优点:

  • 生命周期的管理

GLide#with

@NonNull

public static RequestManager with(@NonNull Context context) {

return getRetriever(context).get(context);

}

@NonNull

public static RequestManager with(@NonNull Activity activity) {

return getRetriever(activity).get(activity);

}

@NonNull

public static RequestManager with(@NonNull FragmentActivity activity) {

return getRetriever(activity).get(activity);

}

@NonNull

public static RequestManager with(@NonNull Fragment fragment) {

return getRetriever(fragment.getActivity()).get(fragment);

}

@Deprecated

@NonNull

public static RequestManager with(@NonNull android.app.Fragment fragment) {

return getRetriever(fragment.getActivity()).get(fragment);

}

可以看到有多个重载方法,主要对两类不同的Context进行不同的处理

  • Application Context 图片加载的生命周期和应用程序一样,肯定是我们不推荐的写法。

  • 其余Context,会像当前Activity创建一个隐藏的Fragment,绑定生命周期。

以Activity为例:

@NonNull

public RequestManager get(@NonNull Activity activity) {

if (Util.isOnBackgroundThread()) {

return get(activity.getApplicationContext());

} else {

//判断是否是销毁状态

assertNotDestroyed(activity);

android.app.FragmentManager fm = activity.getFragmentManager();

//绑定生命周期

return fragmentGet(

activity, fm, /parentHint=/ null, isActivityVisible(activity));

}

}

具体看#fragmentGet()

@NonNull

private RequestManager fragmentGet(@NonNull Context context,

@NonNull android.app.FragmentManager fm,

@Nullable android.app.Fragment parentHint,

boolean isParentVisible) {

//这就是绑定的Fragment,RequestManagerFragment

RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);

RequestManager requestManager = current.getRequestManager();

return requestManager;

}

接着看RequestManagerFragment

public class RequestManagerFragment extends Fragment {

@Override

public void onStart() {

super.onStart();

lifecycle.onStart();

}

@Override

public void onStop() {

super.onStop();

lifecycle.onStop();

}

@Override

public void onDestroy() {

super.onDestroy();

lifecycle.onDestroy();

unregisterFragmentWithRoot();

}

}

关联lifeCycle相应的方法。

简单来说就是通过#with()方法根据穿过来的不同的Context绑定生命周期。

  • Bitmap对象池

Glide提供了一个BitmapPool来保存Bitmap。

简单来说就是当需要加载一个bitmap的时候,会根据图片的参数去池子里找到一个合适的bitmap,如果没有就重新创建。BitMapPool同样是根据Lru算法来工作的。从而提高性能。

  • 高效缓存

缓存相关可以看上文描述,内存和磁盘,磁盘缓存也提供了几种缓存策略。

1.NONE,表示不缓存任何内容

2.SOURCE,表示只缓存原始图片

3.RESULT,表示只缓存转换过后的图片(默认选项)

4.ALL, 表示既缓存原始图片,也缓存转换过后的图片

大厂面试前的复习准备

接下来分享的系统学习资源以详解各大互联网公司的 Android 常见面试题为主线,从面试的角度带你介绍必备知识点,以及该知识点在项目中的实际应用

**帮你在现在的基础上,重新梳理和建立 Android 开发的知识体系。**无论是你短期内想提升 Android 内功实力,突破自己工作中的能力瓶颈,还是准备参加 Android 面试,都会在这份资料中有所一些收获。

从架构基础开始,分了8个模块来逐步从基础进阶到架构师的环节:

多余的话就不讲了,接下来将分享面试的一个复习路线,如果你也在准备面试但是不知道怎么高效复习,可以参考一下我的复习路线,有任何问题也欢迎一起互相交流,加油吧!

首先是超级详细得不能再详细的Android开发学习思维导图,因为图片实在是太大了,所以我就只把二级目录的内容放出来,更加详细的你们可以点击**这里**。

接下来就需要梳理知识,提升储备了!(Android移动架构师七大专题学习资源)

总结

现在新技术层出不穷,如果每次出新的技术,我们都深入的研究的话,很容易分散精力。新的技术可能很久之后我们才会在工作中用得上,当学的新技术无法学以致用,很容易被我们遗忘,到最后真的需要使用的时候,又要从头来过(虽然上手会更快)。

我觉得身为技术人,针对新技术应该是持拥抱态度的,入了这一行你就应该知道这是一个活到老学到老的行业,所以面对新技术,不要抵触,拥抱变化就好了。

Flutter 明显是一种全新的技术,而对于这个新技术在发布之初,花一个月的时间学习它,成本确实过高。但是周末花一天时间体验一下它的开发流程,了解一下它的优缺点、能干什么或者不能干什么。这个时间,并不是我们不能接受的。

如果有时间,其实通读一遍 Flutter 的文档,是最全面的一次对 Flutter 的了解过程。但是如果我们只有 8 小时的时间,我希望能关注一些最值得关注的点。

(跨平台开发(Flutter)、java基础与原理,自定义view、NDK、架构设计、性能优化、完整商业项目开发等)


《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
被我们遗忘,到最后真的需要使用的时候,又要从头来过(虽然上手会更快)。

我觉得身为技术人,针对新技术应该是持拥抱态度的,入了这一行你就应该知道这是一个活到老学到老的行业,所以面对新技术,不要抵触,拥抱变化就好了。

Flutter 明显是一种全新的技术,而对于这个新技术在发布之初,花一个月的时间学习它,成本确实过高。但是周末花一天时间体验一下它的开发流程,了解一下它的优缺点、能干什么或者不能干什么。这个时间,并不是我们不能接受的。

如果有时间,其实通读一遍 Flutter 的文档,是最全面的一次对 Flutter 的了解过程。但是如果我们只有 8 小时的时间,我希望能关注一些最值得关注的点。

(跨平台开发(Flutter)、java基础与原理,自定义view、NDK、架构设计、性能优化、完整商业项目开发等)

[外链图片转存中…(img-EHcA7jUI-1715429025897)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: "failed to resolve: jp.wasabeef:glide-transformations:4.0.0" 是一个编译错误,意味着程序无法解决这个特定的依赖项。 这个错误通出现在使用了依赖管理工具如Gradle或Maven时。它表明在项目构建过程中,无法正确找到并下载所需的依赖项。 有几个见的原因会导致这个错误出现。首先,可能是因为你所使用的库的版本与你在构建文件中指定的版本不一致。在这种情况下,你需要确认库的最新版本,并更新你的构建文件。 其次,可能是因为库的地址错误或库不存在。你可以在Gradle或Maven的存储库中搜索以确定库是否存在,并检查库的名称和地址是否与你在构建文件中使用的版本一致。 最后,可能是由于网络连接错误,导致构建工具无法从存储库中下载依赖项。在这种情况下,你可以尝试使用代理或更改你的网络配置来解决问题。 总之,当你遇到"failed to resolve"的错误时,你需要检查构建文件中的依赖项的版本、地址以及你的网络连接,以确保能够成功解决依赖项。 ### 回答2: 在使用 Glide 图片加载库时出现了 "failed to resolve: jp.wasabeef:glide-transformations:4.0.0" 的错误。这个错误是由于 Gradle 无法解析指定的 Glide 图片转换库版本号4.0.0。 要解决这个问题,可以尝试以下几种方法: 1. 检查版本号:先确保正确的使用了最新版本的 Glide 和转换库。可以打开项目的 build.gradle 文件,查看 Glide 和转换库的版本号,确保二者兼容。 2. 检查依赖项:检查项目的 build.gradle 文件中是否正确添加了依赖项。需要确保在 dependencies 块中添加了正确的 Glide 和转换库依赖项,例如: ``` implementation 'com.github.bumptech.glide:glide:4.12.0' implementation 'jp.wasabeef:glide-transformations:4.3.0' ``` 3. 更新仓库:如果以上两个步骤都没问题,可能是 Gradle 无法从默认的 Maven 仓库中解析到转换库。可以尝试添加 `maven { url 'https://jitpack.io' }` 到项目的 build.gradle 文件中的 repositories 块中,确保 Gradle 可以解析 jitpack 仓库中的依赖。例如: ``` allprojects { repositories { // 其他仓库 maven { url 'https://jitpack.io' } } } ``` 4. 清理缓存:有时 Gradle 缓存可能会引起问题,可以尝试清理 Gradle 缓存并重新构建项目。可以通过在命令行运行 `./gradlew clean` 或者在 Android Studio 中点击 "Build" -> "Clean Project" 来清理缓存。 以上是解决 "failed to resolve: jp.wasabeef:glide-transformations:4.0.0" 错误的一些见方法。根据具体情况选取适合的解决方案,希望能帮到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值