final 코스메틱의 부울 값을 수정할 수 있습니까?
5591 단어 문제 레코드
배경.
며칠 전에 테스트 학생이 이미지와 관련된 버그를 제기했다. 나는 코드를 검사하고 논리를 정리하며 로그를 치고 코드를 디버깅했다.아바타 디스플레이는 Glide 라이브러리의 구성 요소를 사용합니다.대략적인 코드 로직은 다음과 같습니다.
private void setImage(ImageView imageView, String url, final boolean test) {
Log.d(TAG, "setImage, test = " + test);
Glide.with(this)
.asBitmap()
.load(url)
.into(new ImageViewTarget(imageView) {
@Override
protected void setResource(@Nullable Bitmap resource) {
}
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) {
super.onResourceReady(resource, transition);
if (test) {
Log.d(TAG, "onResourceReady, test = " + test);
}
}
});
}
문제.
다른 곳에서 위의 방법(setImage)을 여러 번 사용하고 로그를 쳤는데 그 중에서 이런 상황이 발생했다.
... setImage, test = true
... onResourceReady, test = false
테스트 변수는final 유형으로 이론적으로 나온 로그는 모두true이거나 모두false이므로 하나의true,하나의false가 나타나서는 안 된다.설마 final 수식된boolean 값도 수정할 수 있는 건 아니겠지?
까닭
의심할 필요가 없습니다.final에 의해 수식된boolean 값은 수정할 수 없습니다.문제는 glide에 나타난다.glide 원본의 into 방법을 보았습니다 (glide 버전은 4.5):
private > Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
@NonNull RequestOptions options) {
Util.assertMainThread();
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
options = options.autoClone();
Request request = buildRequest(target, targetListener, options);
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
request.recycle();
// If the request is completed, beginning again will ensure the result is re-delivered,
// triggering RequestListeners and Targets. If the request is failed, beginning again will
// restart the request, giving it another chance to complete. If the request is already
// running, we can let it continue running without interruption.
if (!Preconditions.checkNotNull(previous).isRunning()) {
// Use the previous request rather than the new one to allow for optimizations like skipping
// setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
// that are done in the individual Request.
previous.begin();
}
return target;
}
requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);
return target;
}
원본 코드를 자세히 보면 이곳을 발견할 수 있다.
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
@Override
public boolean isEquivalentTo(Request o) {
if (o instanceof SingleRequest) {
SingleRequest> that = (SingleRequest>) o;
return overrideWidth == that.overrideWidth
&& overrideHeight == that.overrideHeight
&& Util.bothModelsNullEquivalentOrEquals(model, that.model)
&& transcodeClass.equals(that.transcodeClass)
&& requestOptions.equals(that.requestOptions)
&& priority == that.priority
// We do not want to require that RequestListeners implement equals/hashcode, so we don't
// compare them using equals(). We can however, at least assert that the request listener
// is either present or not present in both requests.
&& (requestListener != null
? that.requestListener != null : that.requestListener == null);
}
return false;
}
현재 Request의 설정이 이전의previous 설정과 같고 캐시 건너뛰기 (isSkipMemory CacheWith CompletePrevious Request) 를 설정하지 않으면 이전의previous를 가지고 요청합니다. 현재 구성된 Request는 회수됩니다.문제는 바로 여기에 있다
private void setImage(ImageView imageView, String url, final boolean test) {
Log.d(TAG, "setImage, test = " + test);
Glide.with(this)
.asBitmap()
.load(url)
.into(new ImageViewTarget(imageView) {
@Override
protected void setResource(@Nullable Bitmap resource) {
}
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) {
super.onResourceReady(resource, transition);
if (test) {
Log.d(TAG, "onResourceReady, test = " + test);
}
}
});
}
따라서 위의ImageViewTarget은 새로 구축한 target이 아니라 예전의 낡은 것이기 때문에 위의test 변수의 값은 새로 들어온 것이 아니라 이전에 들어온 것이다.OK, 문제가 해결되었다. 이것은glide의 구덩이이다.
총결산
간단한 문제지만 문제에 부딪히면 원본을 많이 보고 원본을 많이 분석하는 이치를 알려주세요.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
ROS 해결 캣킨make 시 cmake error Invoking "cmake"failed홈페이지 레슨대로 할 때 캣킨make 명령 타임즈 오류CMakeLists.txt:52 (find_package) Configuring incomplete, errors occurred! See also "/home/...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.