Предварительная загрузка или загрузка изображения с Glide - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь загрузить изображения функций блога с страницы блога wordpress, а затем загрузить их позже.

Прямо сейчас, каждый раз, когда пользователь снова и снова прокручивает и загружает изображение. Любая идея ... плззз .. Я пробовал много решений, например, это: Предварительная загрузка нескольких изображений с помощью Glide

Но это не сработало.

Я использую implementation 'com.github.bumptech.glide:glide:3.7.0'

А это мой код:

RecyclerViewAdapter

public void getthumbnail(String imageurl, final ImageView imageView, final int position){

    ServiceWrapper serviceWrapper = new ServiceWrapper(null);
    Call<GetThumbnail> call = serviceWrapper.getThumbnailCall(imageurl);
    call.enqueue(new Callback<GetThumbnail>() {


        @Override
        public void onResponse(Call<GetThumbnail> call, Response<GetThumbnail> response) {
            if (response.body() != null && response.isSuccessful()) {
                try {

                    if (response.body().getMediaDetails()!=null){

                       // Log.e("recycler adapter", " image is here--  " + response.body().getMediaDetails().getSizes().getThumbnail().getSourceUrl());
                       // Log.e("Full IMG SIZE - ", " THIS IS FULL IMAGE URL--  " + response.body().getMediaDetails().getSizes().getFull().getSourceUrl());

                        imagepath.add(position, response.body().getMediaDetails().getSizes().getFull().getSourceUrl());


                        Glide.with(mContext)
                                .load(response.body().getMediaDetails().getSizes().getFull().getSourceUrl())
                                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                                .into(imageView);

                    }else {

                    }
                }catch (Exception e){
                   // Log.e("adapter", "fail not media tag "+ e.toString());
                }

            }
        }

        @Override
        public void onFailure(Call<GetThumbnail> call, Throwable t) {

          //  Log.e("adapter", " faile  image "+t.toString());
        }
    });

}

UPDATE Я нашел этот код и поместил его поверх другого кода Glide, но он не работал:

Glide.with(mContext)
                                .load(response.body().getMediaDetails().getSizes().getFull().getSourceUrl())
                                .downloadOnly(new SimpleTarget<File>() {
                                    @Override
                                    public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {

                                    }
                                });

UPDATE: Теперь я использовал этот код, и он не загружает изображения быстрее:

Glide.with(mContext)
                                .load(response.body().getMediaDetails().getSizes().getFull().getSourceUrl())
                                .downloadOnly(new SimpleTarget<File>() {
                                    @Override
                                    public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {

                                        Glide.with(mContext)
                                                .load(response.body().getMediaDetails().getSizes().getFull().getSourceUrl())
                                                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                                                .into(imageView);
                                    }
                                });

Вот полное ViewAdapter.java

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class RecyclerViewAdapter extends 
RecyclerView.Adapter<RecyclerView.ViewHolder> {

private ArrayList<Model> dataset;
private Context mContext;
private ArrayList<Model> list;
private RecyclerViewAdapter adapter;
private RecyclerView recyclerView;
private LinearLayoutManager mLayoutManager;
public static List<WPPost> mListPost;
ArrayList<String> imagepath = new ArrayList<>();
private String baseURL = "https://www.myfitbytes.com/";

public RecyclerViewAdapter(ArrayList<Model> mlist, Context context) {
    this.dataset = mlist;
    this.mContext = context;
}

public static class ImageTypeViewHolder extends RecyclerView.ViewHolder{


    TextView title, subtitle, date;
    ImageView imageView;
    CardView cardview;

    public ImageTypeViewHolder(View itemView) {
        super(itemView);

        this.title = (TextView)  itemView.findViewById(R.id.title);
        //this.subtitle = (TextView) itemView.findViewById(R.id.subtitle);
        this.date = (TextView) itemView.findViewById(R.id.date);
        this.imageView = (ImageView) itemView.findViewById(R.id.Icon);
        this.cardview = (CardView) itemView.findViewById(R.id.cardview);
    }
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from( parent.getContext()).inflate(R.layout.postdetails, parent, false);





    return new ImageTypeViewHolder(view) ;
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
    final Model object = dataset.get(position);
   // Log.d("RecyclerViewAdapter", "IMAGE="+object.Image);
    imagepath.add(position, "");

    if (Build.VERSION.SDK_INT >= 24)
    {
        //( (ImageTypeViewHolder) holder).subtitle.setText(Html.fromHtml(object.subtitle , Html.FROM_HTML_MODE_LEGACY));
        ( (ImageTypeViewHolder) holder).title.setText( Html.fromHtml(object.title , Html.FROM_HTML_MODE_LEGACY) );
        ( (ImageTypeViewHolder) holder).date.setText( Html.fromHtml(object.date , Html.FROM_HTML_MODE_LEGACY) );
    }
    else
    {
        //( (ImageTypeViewHolder) holder).subtitle.setText(Html.fromHtml(object.subtitle ));
        ( (ImageTypeViewHolder) holder).title.setText( Html.fromHtml(object.title ));
        ( (ImageTypeViewHolder) holder).date.setText( Html.fromHtml(object.date ));
    }


    ( (ImageTypeViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(mContext, WPPostDetails.class);
            intent.putExtra("itemPosition", position);
            mContext.startActivity(intent);
        }
    });



    try {
        getthumbnail(object.Image, ( (ImageTypeViewHolder) holder).imageView, position);



    }catch (Exception e){
     //   Log.e("adapter ","failed to get image "+e.toString() );
    }
    /// dataset.get(position)



}


public void getthumbnail(String imageurl, final ImageView imageView, final int position){

    ServiceWrapper serviceWrapper = new ServiceWrapper(null);
    Call<GetThumbnail> call = serviceWrapper.getThumbnailCall(imageurl);
    call.enqueue(new Callback<GetThumbnail>() {


        @Override
        public void onResponse(Call<GetThumbnail> call, final Response<GetThumbnail> response) {
            if (response.body() != null && response.isSuccessful()) {
                try {

                    if (response.body().getMediaDetails()!=null){

                       // Log.e("recycler adapter", " image is here--  " + response.body().getMediaDetails().getSizes().getThumbnail().getSourceUrl());
                       // Log.e("Full IMG SIZE - ", " THIS IS FULL IMAGE URL--  " + response.body().getMediaDetails().getSizes().getFull().getSourceUrl());

                        imagepath.add(position, response.body().getMediaDetails().getSizes().getFull().getSourceUrl());

                        Glide.with(mContext)
                                .load(response.body().getMediaDetails().getSizes().getFull().getSourceUrl())
                                .downloadOnly(new SimpleTarget<File>() {
                                    @Override
                                    public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {

                                        Glide.with(mContext)
                                                .load(response.body().getMediaDetails().getSizes().getFull().getSourceUrl())
                                                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                                                .into(imageView);
                                    }
                                });


                    }else {

                    }
                }catch (Exception e){
                   // Log.e("adapter", "fail not media tag "+ e.toString());
                }

            }
        }

        @Override
        public void onFailure(Call<GetThumbnail> call, Throwable t) {

          //  Log.e("adapter", " faile  image "+t.toString());
        }
    });

}




@Override
public int getItemCount() {

    return dataset.size() ;
   }
 }

UPDATE Итак, теперь, когда я попытался обновить glide 3 до 4.x, я получаю следующее сообщение об ошибке в build.gradle.

Все библиотеки com.android.support должны использовать одну и ту же спецификацию версий (смешивание версий может привести к сбоям во время выполнения). Найдено версии 27.1.1, 27.1.0, 26.1.0. Примеры включают com.android.support:support-compat:27.1.1 и com.android.support:animated-vector-drawable:27.1.0 less ... (⌘F1) Существуют некоторые комбинации библиотек или инструментов и библиотек, которые несовместимы или могут привести к ошибкам. Одной из таких несовместимостей является компиляция с версией библиотек поддержки Android, которая не является последней версией (или, в частности, версией ниже, чем ваша targetSdkVersion).

И код:

apply plugin: 'com.android.application'

android {
compileSdkVersion 26
  defaultConfig {
    applicationId "com.myfitbytes"
    minSdkVersion 14
    targetSdkVersion 26
    versionCode 3
    versionName "3.0"
    testInstrumentationRunner 
 "android.support.test.runner.AndroidJUnitRunner"
   }
    buildTypes {
     release {
         minifyEnabled false
         proguardFiles getDefaultProguardFile('proguard-android.txt'), 
     'proguard-rules.pro'
    }
}

packagingOptions {
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/notice.txt'
    exclude 'META-INF/ASL2.0'
  }
 }

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'

implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support:support-v4:26.1.0'

//library for wordpress rest api
implementation 'com.android.support:cardview-v7:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.0.0-beta2'
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
implementation 'com.squareup.okhttp:okhttp:2.4.0'
implementation 'com.squareup.okhttp3:okhttp:2.0.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'

  //implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'


implementation 'com.android.volley:volley:1.0.0'

implementation 'org.ocpsoft.prettytime:prettytime:4.0.1.Final'

//Firebase
implementation 'com.google.firebase:firebase-core:16.0.4'
implementation 'com.google.firebase:firebase-messaging:17.3.3'

implementation 'org.apache.httpcomponents:httpcore:4.4.1'
//implementation 'org.apache.httpcomponents:httpclient:4.5.6'
//implementation group: 'org.apache.httpcomponents' , name: 'httpclient- android' , version: '4.3.5.1'

implementation files('libs/google-http-client-1.24.1.jar')
implementation files('libs/httpclient-4.5.3.jar')

//bottom nav
implementation 'com.aurelhubert:ahbottomnavigation:2.1.0'

//picasso to download image from url faster
implementation 'com.squareup.picasso:picasso:2.71828'

testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

 }

 apply plugin: 'com.google.gms.google-services'

И эта строка красного цвета:

implementation 'com.android.support:appcompat-v7:26.1.0'

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

• Прежде всего, я настоятельно рекомендую вам использовать Glide v4.

Проблема задержки загрузки и расположение элемента изображения происходит из метода onBindViewHolder, в котором вы вызываете веб-сервис. Каждый раз, когда элемент прокрутки появляется при прокрутке, вызывается onBindViewHolder для инициализации представления с правильными значениями. Так что вам вообще не следует вызывать веб-сервис (но в коде он вызывается каждый раз). Поскольку Glide создает очередь запросов, это гарантирует, что изображение будет загружено только один раз, потому что оно их кэширует. Также это гарантирует, что изображение будет загружено, если ImageView находится в видимой области RecyclerView в процессе прокрутки. Кроме того, при установке diskCacheStrategy на DiskCacheStrategy.ALL, Glide показывает изображение, которое изменяется в соответствии с размером ImageView.

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
    final Model object = dataset.get(position);

    if (Build.VERSION.SDK_INT >= 24) {
        // ( (ImageTypeViewHolder) holder).subtitle.setText(Html.fromHtml(object.subtitle , Html.FROM_HTML_MODE_LEGACY));
        ((ImageTypeViewHolder) holder).title.setText(Html.fromHtml(object.title , Html.FROM_HTML_MODE_LEGACY));
        ((ImageTypeViewHolder) holder).date.setText(Html.fromHtml(object.date , Html.FROM_HTML_MODE_LEGACY));
    } else {
        // ((ImageTypeViewHolder) holder).subtitle.setText(Html.fromHtml(object.subtitle));
        ((ImageTypeViewHolder) holder).title.setText( Html.fromHtml(object.title));
        ((ImageTypeViewHolder) holder).date.setText( Html.fromHtml(object.date));
    }


    ((ImageTypeViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
           Intent intent = new Intent(mContext, WPPostDetails.class);
           intent.putExtra("itemPosition", position);
           mContext.startActivity(intent);
       }
    });

    Glide.with(imageView.getContext())
         .load(object.Image)
         .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL))
         .into(imageView);
}

С учетом вышеуказанных изменений ваш RecyclerView должен работать так же быстро и без сбоев. Если вы хотите сделать Glide более интегрированным с RecyclerView, вы можете выполнить this . Но я думаю, что в этом нет необходимости, и предыдущего уровня достаточно.

0 голосов
/ 10 ноября 2018

Проблема задержки загрузки и расположение элемента изображения происходят из метода onBindViewHolder, в котором вы вызываете веб-сервис. Каждый раз, когда элемент прокрутки появляется при прокрутке, вызывается onBindViewHolder для инициализации представления с правильными значениями. Так что вам вообще не следует вызывать веб-сервис (но в коде он вызывается каждый раз). Поскольку Glide создает очередь запросов, это гарантирует, что изображение будет загружено только один раз, потому что оно их кэширует. Также это гарантирует, что изображение будет загружено, если ImageView находится в видимой области RecyclerView в процессе прокрутки.

С другой стороны, для достижения URL изображения в вашем случае необходимы два уровня API веб-сервиса. Таким образом, мы должны объединить процедуру Glide и извлекать процедуру URL изображения, чтобы достичь наилучшей производительности. Используя библиотеку Glide-OkHttp3-Integration , я разработал эти два уровня асинхронных вызовов, которые позволяют Glide знать о вашем потоке данных.

• Обратите внимание, что вы должны очистить и перестроить свой проект , чтобы создать GlideApp класс во время компиляции.

ViewAdapter.java

// some code blocks

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
    final Model object = dataset.get(position);

    if (Build.VERSION.SDK_INT >= 24) {
        // ( (ImageTypeViewHolder) holder).subtitle.setText(Html.fromHtml(object.subtitle , Html.FROM_HTML_MODE_LEGACY));
        ((ImageTypeViewHolder) holder).title.setText(Html.fromHtml(object.title , Html.FROM_HTML_MODE_LEGACY));
        ((ImageTypeViewHolder) holder).date.setText(Html.fromHtml(object.date , Html.FROM_HTML_MODE_LEGACY));
    } else {
        // ((ImageTypeViewHolder) holder).subtitle.setText(Html.fromHtml(object.subtitle));
        ((ImageTypeViewHolder) holder).title.setText(Html.fromHtml(object.title));
        ((ImageTypeViewHolder) holder).date.setText(Html.fromHtml(object.date));
    }


    ((ImageTypeViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
           Intent intent = new Intent(mContext, WPPostDetails.class);
           intent.putExtra("itemPosition", position);
           mContext.startActivity(intent);
       }
    });

    JsonApiGlideUrl url = new JsonApiGlideUrl(object.Image);
    GlideApp.with(imageView.getContext())
         .load(url)
         .into(imageView);
}

// some code blocks

OkHttpAppGlideModule.java

import android.content.Context;
import android.support.annotation.NonNull;

import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;

import java.io.InputStream;

/**
 * Registers OkHttp related classes via Glide's annotation processor.
 *
 * <p>For Applications that depend on this library and include an
 * {@link AppGlideModule} and Glide's annotation processor, this class
 * will be automatically included.
 */
@GlideModule
public final class OkHttpAppGlideModule extends AppGlideModule {

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        registry.replace(JsonApiGlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
    }

    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }

}

JsonApiGlideUrl.java

import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.Headers;

import java.net.URL;

public class JsonApiGlideUrl extends GlideUrl {

    public JsonApiGlideUrl(URL url) {
        super(url);
    }

    public JsonApiGlideUrl(String url) {
        super(url);
    }

    public JsonApiGlideUrl(URL url, Headers headers) {
        super(url, headers);
    }

    public JsonApiGlideUrl(String url, Headers headers) {
        super(url, headers);
    }

}

OkHttpUrlLoader.java

import android.support.annotation.NonNull;

import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.MultiModelLoaderFactory;

import java.io.InputStream;

import okhttp3.Call;
import okhttp3.OkHttpClient;

/**
 * A simple model loader for fetching media over http/https using OkHttp.
 */
public class OkHttpUrlLoader implements ModelLoader<JsonApiGlideUrl, InputStream> {

    private final Call.Factory client;

    // Public API.
    @SuppressWarnings("WeakerAccess")
    public OkHttpUrlLoader(@NonNull Call.Factory client) {
        this.client = client;
    }

    @Override
    public boolean handles(@NonNull JsonApiGlideUrl url) {
        return true;
    }

    @Override
    public LoadData<InputStream> buildLoadData(@NonNull JsonApiGlideUrl model, int width, int height, @NonNull Options options) {
        return new LoadData<>(model, new OkHttpStreamFetcher(client, model));
    }

    /**
     * The default factory for {@link OkHttpUrlLoader}s.
     */
    // Public API.
    @SuppressWarnings("WeakerAccess")
    public static class Factory implements ModelLoaderFactory<JsonApiGlideUrl, InputStream> {

        private static volatile Call.Factory internalClient;
        private final Call.Factory client;

        private static Call.Factory getInternalClient() {
            if (internalClient == null) {
                synchronized (Factory.class) {
                    if (internalClient == null) {
                        internalClient = new OkHttpClient();
                    }
                }
            }
            return internalClient;
        }

        /**
         * Constructor for a new Factory that runs requests using a static singleton client.
         */
        public Factory() {
            this(getInternalClient());
        }

        /**
         * Constructor for a new Factory that runs requests using given client.
         *
         * @param client this is typically an instance of {@code OkHttpClient}.
         */
        public Factory(@NonNull Call.Factory client) {
            this.client = client;
        }

        @NonNull
        @Override
        public ModelLoader<JsonApiGlideUrl, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
            return new OkHttpUrlLoader(client);
        }

        @Override
        public void teardown() {
            // Do nothing, this instance doesn't own the client.
        }

    }

}

OkHttpStreamFetcher.java

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.bumptech.glide.Priority;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.HttpException;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.util.ContentLengthInputStream;
import com.bumptech.glide.util.Preconditions;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * Fetches an {@link InputStream} using the okhttp library.
 */
public class OkHttpStreamFetcher implements DataFetcher<InputStream>, okhttp3.Callback {

    private static final String TAG = "OkHttpFetcher";
    private final Call.Factory client;
    private final JsonApiGlideUrl url;
    private OkHttpJsonApiFetcher okHttpJsonApiFetcher;
    private InputStream stream;
    private ResponseBody responseBody;
    private DataCallback<? super InputStream> callback;
    // call may be accessed on the main thread while the object is in use on other threads. All other
    // accesses to variables may occur on different threads, but only one at a time.
    private volatile Call call;

    // Public API.
    @SuppressWarnings("WeakerAccess")
    public OkHttpStreamFetcher(Call.Factory client, JsonApiGlideUrl url) {
        this.client = client;
        this.url = url;
    }

    @Override
    public void loadData(@NonNull Priority priority, @NonNull final DataCallback<? super InputStream> callback) {

        okHttpJsonApiFetcher = new OkHttpJsonApiFetcher(client, url);
        okHttpJsonApiFetcher.loadData(new DataCallback<GlideUrl>() {

            @Override
            public void onDataReady(@Nullable GlideUrl data) {
                Request.Builder requestBuilder = new Request.Builder().url(data.toStringUrl());
                for (Map.Entry<String, String> headerEntry : data.getHeaders().entrySet()) {
                    String key = headerEntry.getKey();
                    requestBuilder.addHeader(key, headerEntry.getValue());
                }
                Request request = requestBuilder.build();
                OkHttpStreamFetcher.this.callback = callback;

                call = client.newCall(request);
                call.enqueue(OkHttpStreamFetcher.this);
            }

            @Override
            public void onLoadFailed(@NonNull Exception e) {
                callback.onLoadFailed(e);
            }
        });
    }

    @Override
    public void onFailure(@NonNull Call call, @NonNull IOException e) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "OkHttp failed to obtain result", e);
        }
        callback.onLoadFailed(e);
    }

    @Override
    public void onResponse(@NonNull Call call, @NonNull Response response) {
        responseBody = response.body();
        if (response.isSuccessful()) {
            long contentLength = Preconditions.checkNotNull(responseBody).contentLength();
            stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);
            callback.onDataReady(stream);
        } else {
            callback.onLoadFailed(new HttpException(response.message(), response.code()));
        }
    }

    @Override
    public void cleanup() {
        okHttpJsonApiFetcher.cleanup();

        try {
            if (stream != null) {
                stream.close();
            }
        } catch (IOException e) {
            // Ignored
        }
        if (responseBody != null) {
            responseBody.close();
        }
        callback = null;
    }

    @Override
    public void cancel() {
        okHttpJsonApiFetcher.cancel();

        Call local = call;
        if (local != null) {
            local.cancel();
        }
    }

    @NonNull
    @Override
    public Class<InputStream> getDataClass() {
        return InputStream.class;
    }

    @NonNull
    @Override
    public DataSource getDataSource() {
        return DataSource.REMOTE;
    }

}

OkHttpJsonApiFetcher.java

import android.support.annotation.NonNull;
import android.util.Log;

import com.bumptech.glide.load.HttpException;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GlideUrl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * Fetches an {@link InputStream} using the okhttp library.
 */
public class OkHttpJsonApiFetcher implements okhttp3.Callback {

    private static final String TAG = "OkHttpJsonApiFetcher";
    private final Call.Factory client;
    private final JsonApiGlideUrl url;
    private ResponseBody responseBody;
    private DataFetcher.DataCallback<? super GlideUrl> callback;
    // call may be accessed on the main thread while the object is in use on other threads. All other
    // accesses to variables may occur on different threads, but only one at a time.
    private volatile Call call;

    // Public API.
    @SuppressWarnings("WeakerAccess")
    public OkHttpJsonApiFetcher(Call.Factory client, JsonApiGlideUrl url) {
        this.client = client;
        this.url = url;
    }

    public void loadData(@NonNull final DataFetcher.DataCallback<? super GlideUrl> callback) {
        Request.Builder requestBuilder = new Request.Builder().get().url(url.toStringUrl());
        for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {
            String key = headerEntry.getKey();
            requestBuilder.addHeader(key, headerEntry.getValue());
        }
        Request request = requestBuilder.build();
        this.callback = callback;

        call = client.newCall(request);
        call.enqueue(this);
    }

    @Override
    public void onFailure(@NonNull Call call, @NonNull IOException e) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "OkHttp failed to obtain result", e);
        }
        callback.onLoadFailed(e);
    }

    @Override
    public void onResponse(@NonNull Call call, @NonNull Response response) {
        responseBody = response.body();
        if (response.isSuccessful() && responseBody != null) {
            try {
                String json = responseBody.string();
                String url = JsonApiDataModel.getSourceUrl(json);
                callback.onDataReady(new GlideUrl(url));
            } catch (IOException e) {
                callback.onLoadFailed(new HttpException(response.message(), response.code()));
                e.printStackTrace();
            }
        } else {
            callback.onLoadFailed(new HttpException(response.message(), response.code()));
        }
    }

    public void cleanup() {
        if (responseBody != null) {
            responseBody.close();
        }
        callback = null;
    }

    public void cancel() {
        Call local = call;
        if (local != null) {
            local.cancel();
        }
    }

}

JsonApiDataModel.java

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;

public class JsonApiDataModel {

    @SerializedName("media_details")
    MediaDetails mediaDetails;

    public static String getSourceUrl(String json) {
        return new Gson().fromJson(json, JsonApiDataModel.class).mediaDetails.sizes.full.sourceUrl;
    }

    public class MediaDetails {
        @SerializedName("sizes")
        Sizes sizes;
    }

    public class Sizes {
        // you can use full, medium or thumbnail here!
        @SerializedName("full")
        Full full;
    }

    public class Full {
        @SerializedName("source_url")
        String sourceUrl;
    }

}

.

Тестовый код и визуальный результат:

import com.aminography.glideapplication.glide.okhttp3.GlideApp;
import com.aminography.glideapplication.glide.okhttp3.JsonApiGlideUrl;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final ImageView imageView = findViewById(R.id.imageView);
        TextView textView = findViewById(R.id.textView);

        String sourceUrl = "https://www.myfitbytes.com/wp-json/wp/v2/media/2811";

        textView.setText("JsonApiGlideUrl:\n\n" + sourceUrl);

        final JsonApiGlideUrl url = new JsonApiGlideUrl(sourceUrl);
        GlideApp.with(MainActivity.this).load(url).into(imageView);
    }

}

enter image description here

0 голосов
/ 06 ноября 2018

Текущая версия Glide - 4.8.0. По какой причине вы не хотите работать с этой версией? https://github.com/bumptech/glide

https://github.com/bumptech/glide/blob/master/samples/flickr/src/main/java/com/bumptech/glide/samples/flickr/FlickrPhotoGrid.java

Вам необходимо использовать RecyclerView. Вот пример:

 grid.addItemDecoration(new RecyclerView.ItemDecoration() {
      @Override
      public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
          RecyclerView.State state) {
        outRect.set(gridMargin, gridMargin, gridMargin, gridMargin);
      }
    });
    grid.setRecyclerListener(new RecyclerView.RecyclerListener() {
      @Override
      public void onViewRecycled(RecyclerView.ViewHolder holder) {
        PhotoViewHolder photoViewHolder = (PhotoViewHolder) holder;
        GlideApp.with(FlickrPhotoGrid.this).clear(photoViewHolder.imageView);
      }
    });
...