@Override public boolean onLoadFailed(GlideException e, Object model, Target<PictureDrawable> target, boolean isFirstResource) { ImageView view = ((ImageViewTarget<?>) target).getView(); view.setLayerType(ImageView.LAYER_TYPE_NONE, null); return false; }
public void setImageUrls(Collection<String> imageUrls) { // clean up outdated stuff for (Target target : mTargets) { Glide.clear(target); // clears mBitmaps[i] as well } if (imageUrls == null) imageUrls = Collections.emptyList(); int newSize = imageUrls.size(); mImageUrls = imageUrls.toArray(new String[newSize]); mBitmaps = new Bitmap[newSize]; mDrawRects = new RectF[newSize]; mTargets = new Target[newSize]; if (!haveRule) { mColumns = imageUrls.size() <= 4 ? 2 : 3; } for (int i = 0; i < imageUrls.size(); i++) { mTargets[i] = new PositionTarget(i); } requestLayout(); }
@Override public final Resource<Bitmap> transform( Context context, Resource<Bitmap> resource, int outWidth, int outHeight) { if (!Util.isValidDimensions(outWidth, outHeight)) { throw new IllegalArgumentException( "Cannot apply transformation on width: " + outWidth + " or height: " + outHeight + " less than or equal to zero and not Target.SIZE_ORIGINAL"); } BitmapPool bitmapPool = Glide.get(context).getBitmapPool(); Bitmap toTransform = resource.get(); int targetWidth = outWidth == Target.SIZE_ORIGINAL ? toTransform.getWidth() : outWidth; int targetHeight = outHeight == Target.SIZE_ORIGINAL ? toTransform.getHeight() : outHeight; Bitmap transformed = transform(bitmapPool, toTransform, targetWidth, targetHeight); final Resource<Bitmap> result; if (toTransform.equals(transformed)) { result = resource; } else { result = BitmapResource.obtain(transformed, bitmapPool); } return result; }
/** * Set the target the resource will be loaded into. * * @param target The target to load the resource into. * @return The given target. * @see RequestManager#clear(Target) */ public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) { Util.assertMainThread(); Preconditions.checkNotNull(target); if (!isModelSet) { throw new IllegalArgumentException("You must call #load() before calling #into()"); } Request previous = target.getRequest(); if (previous != null) { requestManager.clear(target); } requestOptions.lock(); Request request = buildRequest(target); target.setRequest(request); requestManager.track(target, request); return target; }
/** * Sets the {@link ImageView} the resource will be loaded into, cancels any existing loads into * the view, and frees any resources Glide may have previously loaded into the view so they may be * reused. * * @see RequestManager#clear(Target) * * @param view The view to cancel previous loads for and load the new resource into. * @return The * {@link com.bumptech.glide.request.target.Target} used to wrap the given {@link ImageView}. */ public Target<TranscodeType> into(ImageView view) { Util.assertMainThread(); Preconditions.checkNotNull(view); if (!requestOptions.isTransformationSet() && requestOptions.isTransformationAllowed() && view.getScaleType() != null) { if (requestOptions.isLocked()) { requestOptions = requestOptions.clone(); } switch (view.getScaleType()) { case CENTER_CROP: requestOptions.optionalCenterCrop(); break; case CENTER_INSIDE: requestOptions.optionalCenterInside(); break; case FIT_CENTER: case FIT_START: case FIT_END: requestOptions.optionalFitCenter(); break; case FIT_XY: requestOptions.optionalCenterInside(); break; case CENTER: case MATRIX: default: // Do nothing. } } return into(context.buildImageViewTarget(view, transcodeClass)); }
private Request obtainRequest(Target<TranscodeType> target, RequestOptions requestOptions, RequestCoordinator requestCoordinator, TransitionOptions<?, ? super TranscodeType> transitionOptions, Priority priority, int overrideWidth, int overrideHeight) { requestOptions.lock(); return SingleRequest.obtain( context, model, transcodeClass, requestOptions, overrideWidth, overrideHeight, priority, target, requestListener, requestCoordinator, context.getEngine(), transitionOptions.getTransitionFactory()); }
@Before public void setUp() throws Exception { Glide.tearDown(); RobolectricPackageManager pm = RuntimeEnvironment.getRobolectricPackageManager(); ApplicationInfo info = pm.getApplicationInfo(RuntimeEnvironment.application.getPackageName(), 0); info.metaData = new Bundle(); info.metaData.putString(SetupModule.class.getName(), "GlideModule"); // Ensure that target's size ready callback will be called synchronously. target = mock(Target.class); imageView = new ImageView(RuntimeEnvironment.application); imageView.setLayoutParams(new ViewGroup.LayoutParams(100, 100)); imageView.layout(0, 0, 100, 100); doAnswer(new CallSizeReady()).when(target).getSize(isA(SizeReadyCallback.class)); Handler bgHandler = mock(Handler.class); when(bgHandler.post(isA(Runnable.class))).thenAnswer(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { Runnable runnable = (Runnable) invocation.getArguments()[0]; runnable.run(); return true; } }); Lifecycle lifecycle = mock(Lifecycle.class); RequestManagerTreeNode treeNode = mock(RequestManagerTreeNode.class); requestManager = new RequestManager(Glide.get(getContext()), lifecycle, treeNode); requestManager.resumeRequests(); }
@Test public void testClone() throws IOException { Target<Drawable> firstTarget = mock(Target.class); doAnswer(new CallSizeReady(100, 100)).when(firstTarget).getSize(isA(SizeReadyCallback.class)); Target<Drawable> secondTarget = mock(Target.class); doAnswer(new CallSizeReady(100, 100)).when(secondTarget).getSize(isA(SizeReadyCallback.class)); RequestBuilder<Drawable> firstRequest = requestManager .load(mockUri("content://first")); firstRequest.into(firstTarget); firstRequest.clone() .apply(placeholderOf(new ColorDrawable(Color.RED))) .into(secondTarget); verify(firstTarget).onResourceReady(isA(Drawable.class), isA(Transition.class)); verify(secondTarget).onResourceReady(notNull(Drawable.class), isA(Transition.class)); }
@Override public boolean onResourceReady(PictureDrawable resource, Object model, Target<PictureDrawable> target, DataSource dataSource, boolean isFirstResource) { ImageView view = ((ImageViewTarget<?>) target).getView(); view.setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null); return false; }
@TargetApi(VERSION_CODES.ICE_CREAM_SANDWICH) private void showContact(long id) { GlideRequests glideRequests = GlideApp.with(this); RequestOptions originalSize = new RequestOptions().override(Target.SIZE_ORIGINAL); Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id); glideRequests.load(contactUri).apply(originalSize).into(imageViewContact); Uri lookupUri = Contacts.getLookupUri(getContentResolver(), contactUri); glideRequests.load(lookupUri).apply(originalSize).into(imageViewLookup); Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY); glideRequests.load(photoUri).apply(originalSize).into(imageViewPhoto); if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) { Uri displayPhotoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.DISPLAY_PHOTO); glideRequests.load(displayPhotoUri).apply(originalSize).into(imageViewDisplayPhoto); } }
/** * 保存图片到本地 * * @param fileName 文件名 */ private void saveImageToLocal(final String fileName) { Observable.create(new ObservableOnSubscribe<File>() { @Override public void subscribe(ObservableEmitter<File> e) throws Exception { e.onNext(Glide.with(ImageBrowseActivity.this) .load(mImageUrl) .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .get()); e.onComplete(); } }).compose(RxHelper.<File>rxSchedulerHelper()).subscribe(new Consumer<File>() { @Override public void accept(File file) throws Exception { saveImage(fileName, file); } }); }
/** * Cancel any pending loads Glide may have for the target and free any resources (such as * {@link Bitmap}s) that may have been loaded for the target so they may be reused. * * @param target The Target to cancel loads for. */ public void clear(@Nullable final Target<?> target) { if (target == null) { return; } if (Util.isOnMainThread()) { untrackOrDelegate(target); } else { mainHandler.post(new Runnable() { @Override public void run() { clear(target); } }); } }
private void untrackOrDelegate(Target<?> target) { boolean isOwnedByUs = untrack(target); // We'll end up here if the Target was cleared after the RequestManager that started the request // is destroyed. That can happen for at least two reasons: // 1. We call clear() on a background thread using something other than Application Context // RequestManager. // 2. The caller retains a reference to the RequestManager after the corresponding Activity or // Fragment is destroyed, starts a load with it, and then clears that load with a different // RequestManager. Callers seem especially likely to do this in retained Fragments (#2262). // // #1 is always an error. At best the caller is leaking memory briefly in something like an // AsyncTask. At worst the caller is leaking an Activity or Fragment for a sustained period of // time if they do something like reference the Activity RequestManager in a long lived // background thread or task. // // #2 is always an error. Callers shouldn't be starting new loads using RequestManagers after // the corresponding Activity or Fragment is destroyed because retaining any reference to the // RequestManager leaks memory. It's possible that there's some brief period of time during or // immediately after onDestroy where this is reasonable, but I can't think of why. if (!isOwnedByUs && !glide.removeFromManagers(target) && target.getRequest() != null) { Request request = target.getRequest(); target.setRequest(null); request.clear(); } }
@Override public boolean onResourceReady( GlideDrawable resource, GlideUrl uri, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource ) { if (!(target instanceof ImageViewTarget)) { return false; } ImageViewWithUrl view = (ImageViewWithUrl) ((ImageViewTarget) target).getView(); ThemedReactContext context = (ThemedReactContext) view.getContext(); RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class); int viewId = view.getId(); eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_EVENT, new WritableNativeMap()); eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_END_EVENT, new WritableNativeMap()); return false; }
private Request obtainRequest( Target<TranscodeType> target, RequestListener<TranscodeType> targetListener, RequestOptions requestOptions, RequestCoordinator requestCoordinator, TransitionOptions<?, ? super TranscodeType> transitionOptions, Priority priority, int overrideWidth, int overrideHeight) { return SingleRequest.obtain( context, glideContext, model, transcodeClass, requestOptions, overrideWidth, overrideHeight, priority, target, targetListener, requestListener, requestCoordinator, glideContext.getEngine(), transitionOptions.getTransitionFactory()); }
public static <R> SingleRequest<R> obtain( GlideContext glideContext, Object model, Class<R> transcodeClass, RequestOptions requestOptions, int overrideWidth, int overrideHeight, Priority priority, Target<R> target, RequestListener<R> requestListener, RequestCoordinator requestCoordinator, Engine engine, TransitionFactory<? super R> animationFactory) { @SuppressWarnings("unchecked") SingleRequest<R> request = (SingleRequest<R>) POOL.acquire(); if (request == null) { request = new SingleRequest<>(); } request.init( glideContext, model, transcodeClass, requestOptions, overrideWidth, overrideHeight, priority, target, requestListener, requestCoordinator, engine, animationFactory); return request; }
private void init( GlideContext glideContext, Object model, Class<R> transcodeClass, RequestOptions requestOptions, int overrideWidth, int overrideHeight, Priority priority, Target<R> target, RequestListener<R> requestListener, RequestCoordinator requestCoordinator, Engine engine, TransitionFactory<? super R> animationFactory) { this.glideContext = glideContext; this.model = model; this.transcodeClass = transcodeClass; this.requestOptions = requestOptions; this.overrideWidth = overrideWidth; this.overrideHeight = overrideHeight; this.priority = priority; this.target = target; this.requestListener = requestListener; this.requestCoordinator = requestCoordinator; this.engine = engine; this.animationFactory = animationFactory; status = Status.PENDING; }
/** * 利用glide加载图片时,一定要放在线程中,不然会报错 */ @Override public void run() { final String imageUrl = getPositionImage(); Bitmap bitmap = null; try { bitmap = Glide.with(view.getMyContext()).asBitmap().load(imageUrl).into(Target.SIZE_ORIGINAL, Target .SIZE_ORIGINAL).get(); if (bitmap!=null){ saveBitmap(bitmap,imageUrl); } }catch (Exception e){ e.printStackTrace(); } }
@Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { if (mBitmapListener != null){ mBitmapListener.onFailure(e); } return false; }
@Override public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { synchronized (this) { if (image.getGifUrl().equals(model)) { this.modelReady = true; notifyAll(); } } return false; }
public BitmapRequestBuilder<?, BitmapPaletteWrapper> build() { //noinspection unchecked return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload) .asBitmap() .transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class) .diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY) .error(DEFAULT_ERROR_IMAGE) .animate(DEFAULT_ANIMATION) .priority(Priority.LOW) .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .signature(createSignature(builder.artist)); }
@Override protected void loadImage(String url, final OnResourceReadyListener listener) { Glide.with(ExampleActivity.this) .load(Uri.parse(url).normalizeScheme()) .asBitmap().transform(transformation) .diskCacheStrategy( DiskCacheStrategy.ALL) .into(new SimpleTarget<Bitmap>(width, Target.SIZE_ORIGINAL) { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { // must call this when bitmap resource is ready listener.onResourceReady(resource); } }); }
@Override public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { mCircleProgressView.setVisibility(View.GONE); mCircleProgressView.stopSpinning(); mImageView.setImageDrawable(resource); mPhotoViewAttacher = new PhotoViewAttacher(mImageView); mPhotoViewAttacher.setOnViewTapListener((view, v, v1) -> getActivity().finish()); return false; }
@Override public void clear(final Context ctx, GlideImageConfig config) { if (ctx == null) throw new IllegalStateException("Context is required"); if (config == null) throw new IllegalStateException("GlideImageConfig is required"); if (config.getImageViews() != null && config.getImageViews().length > 0) {//取消在执行的任务并且释放资源 for (ImageView imageView : config.getImageViews()) { GlideApp.with(ctx).clear(imageView); } } if (config.getTargets() != null && config.getTargets().length > 0) {//取消在执行的任务并且释放资源 for (Target target : config.getTargets()) GlideApp.with(ctx).clear(target); } if (config.isClearDiskCache()) {//清除本地缓存 Observable.just(0) .observeOn(Schedulers.io()) .subscribe(new Consumer<Integer>() { @Override public void accept(@NonNull Integer integer) throws Exception { GlideApp.get(ctx).clearDiskCache(); } }); } if (config.isClearMemory()) {//清除内存缓存 Glide.get(ctx).clearMemory(); } }
private void initView() { mCircleProgressView.setVisibility(View.VISIBLE); mCircleProgressView.spin(); Glide.with(this).load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .crossFade(0) .listener(this) .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL); }
private void saveToFile() { if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(this, R.string.gallery_save_file_not_have_external_storage, Toast.LENGTH_SHORT).show(); return; } final Future<File> future = getImageLoader() .load(mPath) .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL); AppOperator.runOnThread(new Runnable() { @Override public void run() { try { File sourceFile = future.get(); if (sourceFile == null || !sourceFile.exists()) return; String extension = BitmapUtil.getExtension(sourceFile.getAbsolutePath()); String extDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) .getAbsolutePath() + File.separator + "开源中国"; File extDirFile = new File(extDir); if (!extDirFile.exists()) { if (!extDirFile.mkdirs()) { // If mk dir error callSaveStatus(false, null); return; } } final File saveFile = new File(extDirFile, String.format("IMG_%s.%s", System.currentTimeMillis(), extension)); final boolean isSuccess = StreamUtil.copyFile(sourceFile, saveFile); callSaveStatus(isSuccess, saveFile); } catch (Exception e) { e.printStackTrace(); callSaveStatus(false, null); } } }); }
public DrawableRequestBuilder<GlideDrawable> build() { //noinspection unchecked return createBaseRequest(requestManager, artist, noCustomImage, forceDownload) .diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY) .error(DEFAULT_ERROR_IMAGE) .animate(DEFAULT_ANIMATION) .priority(Priority.LOW) .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .signature(createSignature(artist)); }
@Override public void loadPreview(long currentPosition, long max) { player.setPlayWhenReady(false); GlideApp.with(imageView) .load(thumbnailsUrl) .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .transform(new GlideThumbnailTransformation(currentPosition)) .into(imageView); }
private <R> List<Integer> getTargetsSizes( RequestBuilder<R> requestBuilder, VerificationMode mode) { ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<Target<R>> targetArgumentCaptor = cast(ArgumentCaptor.forClass(Target.class)); SizeReadyCallback cb = mock(SizeReadyCallback.class); verify(requestBuilder, mode).into(targetArgumentCaptor.capture()); for (Target<R> target : targetArgumentCaptor.getAllValues()) { target.getSize(cb); } verify(cb, mode).onSizeReady(integerArgumentCaptor.capture(), integerArgumentCaptor.capture()); return integerArgumentCaptor.getAllValues(); }
@Test public void testCallsTransformWithGivenBitmapWidthIfWidthIsSizeOriginal() { SizeTrackingTransform transform = new SizeTrackingTransform(); int expectedWidth = 200; Resource<Bitmap> resource = mockResource(expectedWidth, 300); transform.transform(context, resource, Target.SIZE_ORIGINAL, 500); assertEquals(expectedWidth, transform.givenWidth); }
/** * Glide 释放资源 * * @param ctx * @param config */ @Override public void clear(final Context ctx, GlideImageConfig config) { if (ctx == null) throw new IllegalStateException("Context is required"); if (config == null) throw new IllegalStateException("GlideImageConfig is required"); if (config.getImageViews() != null && config.getImageViews().length > 0) {//取消在执行的任务并且释放资源 for (ImageView imageView : config.getImageViews()) { Glide.clear(imageView); } } if (config.getTargets() != null && config.getTargets().length > 0) {//取消在执行的任务并且释放资源 for (Target target : config.getTargets()) Glide.clear(target); } if (config.isClearDiskCache()) {//清除本地缓存 Observable.just(0) .observeOn(Schedulers.io()) .subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { Glide.get(ctx).clearDiskCache(); } }); } if (config.isClearMemory()) {//清除内存缓存 Glide.get(ctx).clearMemory(); } }
/** * 获取图片宽高 * @author leibing * @createTime 2017/2/28 * @lastModify 2017/2/28 * @param context 上下文 * @param url 图片链接 * @param callback 图片加载回调 * @return */ public void getImgWidthHeight(Context context, String url, final ImageLoaderCallBack callback){ Glide.with(context) .load(url) .asBitmap() .into(new SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) { @Override public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) { if (callback != null){ callback.getImgWidthHeight(bitmap.getWidth(), bitmap.getHeight()); } } }); }
@Test(expected = RuntimeException.class) public void testThrowsIfIntoTargetCalledOnBackgroundThread() throws InterruptedException { final Target<Object> target = mock(Target.class); testInBackground(new BackgroundUtil.BackgroundTester() { @Override public void runTest() throws Exception { getNullModelRequest().into(target); } }); }
private RequestBuilder<Object> getNullModelRequest() { when(glideContext.buildImageViewTarget(isA(ImageView.class), isA(Class.class))) .thenReturn(mock(Target.class)); when(glideContext.getDefaultRequestOptions()).thenReturn(new RequestOptions()); when(requestManager.getDefaultRequestOptions()) .thenReturn((RequestOptions) new RequestOptions()); return new RequestBuilder<>(glide, requestManager, Object.class) .load((Object) null); }
/** * 计算图片分辨率 * * @param context * @param url * @return * @throws ExecutionException * @throws InterruptedException */ public static String calePhotoSize(Context context, String url) throws ExecutionException, InterruptedException { File file = Glide.with(context).load(url) .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get(); // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(file.getAbsolutePath(), options); return options.outWidth + "*" + options.outHeight; }
@Override public boolean onResourceReady(T resource, Object model, Target<T> target, DataSource dataSource, boolean isFirstResource) { mainHandler.post(new Runnable() { @Override public void run() { countDownLatch.countDown(); } }); return false; }
public static File loadWithGlideCache(String path) { File tmp; try { tmp = Glide.with(AppContext.getInstance()) .load(path) .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .get(); String absPath = tmp.getAbsolutePath(); TLog.d("PicturesCompressor", "loadWithGlideCache:" + absPath); return tmp; } catch (Exception e) { e.printStackTrace(); return null; } }
@Override public void getSize(SizeReadyCallback cb) { // FIXME 这里为了图方面,直接加载原图了,生产环境上应该是高和宽都取mView.getDrawableSize()。 // 但是这里直接取的话也不一定能取到正确的值,所以建义在 // android.view.ViewTreeObserver.OnPreDrawListener中做处理。 // 另外,DrawableSize会因图片数量改变而改变,所以建义异步加载图像之前 // 应当先设置占位图。如果图片的数量是动态可变的的话,也建义做针对性处理。 cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL); }