Отображение изображений с помощью URL или загрузки на устройство?

#android #firebase #picasso #firebaseui

#Android #firebase #пикассо #firebaseui

Вопрос:

Я использую пользовательский интерфейс Firebase с карточками RecyclerView, и на каждой карточке есть текст и небольшое изображение (90dp / 90dp). Я не загружаю изображения на устройство, я получаю URI изображения и, используя getDownloadUrl() метод, получаю URL-адрес изображения и показываю его с помощью Picasso.

Проблема в том, что если в RecyclerView много записей, обновление изображений занимает некоторое время, если я прокручиваю страницу до нижней или верхней части.

Например, если я быстро прокручиваю страницу вниз, на секунду отображаются изображения, отображаемые в верхней части страницы, прежде чем показывать реальные изображения, которые должны быть там.

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

Спасибо.

Комментарии:

1. используйте glide и кэшируйте изображения

2. Ваш вопрос в первую очередь основан на мнении . С учетом сказанного, почему бы просто не использовать изображение по умолчанию, которое будет отображаться в ожидании загрузки соответствующих изображений?

3. Знаете ли вы ответ, мистер ЭЛ?

Ответ №1:

Например, если я быстро прокручиваю страницу вниз, на секунду отображаются изображения, отображаемые в верхней части страницы, прежде чем показывать реальные изображения, которые должны быть там.

Причина, по которой вы видите старые изображения для новых мест, заключается в том, что RecylerView перерабатывает свои представления. Итак, к тому времени getDownloadUrl() в следующем коде,

 getDownloadUrl().addOnCompleteListener(task -> {
           if (task.isSuccessful()) {
               Picasso.with(context).
               load(task.getResult())
               into(holder.imageView);

           }
       });
  

разрешено ли предполагаемое представление, возможно, может быть переработано для отображения содержимого в другой позиции (в вашем случае при прокрутке вниз появляется новый элемент внизу списка).

В общем, будьте осторожны с использованием обратных вызовов для загрузки любых данных внутри onBindViewHolder метода адаптеров просмотра recycler.

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

Локальная загрузка содержимого изображения с последующим отображением действительно обеспечит наилучший пользовательский интерфейс, особенно если загружаемый контент не сильно меняется. Это также снизит ваши расходы на выставление счетов firebase, поскольку вам выставляется счет за загруженный ГБ. Но вам не нужно реализовывать это вручную.

Решение

Сначала используйте пользовательский обработчик запросов firebase для обработки URL-адресов хранилища firebase, например gs://somefirebasepath/somefile . в этом load методе реализована ваша логика кэширования.

 import android.graphics.BitmapFactory;
import android.util.Log;

import com.google.android.gms.tasks.Tasks;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.StreamDownloadTask;
import com.squareup.picasso.Request;
import com.squareup.picasso.RequestHandler;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;

import static com.squareup.picasso.Picasso.LoadedFrom.NETWORK;

public class FirebasePicassoRequestHandler extends RequestHandler {
    @Override
    public boolean canHandleRequest(Request data) {
        return data.uri != null amp;amp; "gs".equals(data.uri.getScheme();
    }

    @Override
    public Result load(Request request, int networkPolicy) throws IOException {
        //Implement your caching logic here, or load from network as follows
        StorageReference gsReference = FirebaseStorage.getInstance().getReferenceFromUrl(request.uri.toString());

        StreamDownloadTask mStreamTask;

        InputStream inputStream ;

        mStreamTask = gsReference.getStream();

        try {
            inputStream = Tasks.await(mStreamTask).getStream();
            Log.i("FireBaseRequestHandler", "Loaded "   gsReference.getPath() );
            return new Result(BitmapFactory.decodeStream(inputStream), NETWORK);
        } catch (ExecutionException e) {
            throw new IOException();
        } catch (InterruptedException e) {
            throw new IOException();
        }
    }
}   
  

И использовать Picasso.Builder для создания экземпляра Picasso. И добавьте свой пользовательский обработчик в Picasso. При желании вы можете добавить прослушиватель ошибок, чтобы помочь отлаживать проблемы с обработчиком, если они возникают.

     Picasso.Builder builder = new Picasso.Builder(this);

    builder.addRequestHandler(new FirebasePicassoRequestHandler());
    builder.listener(new Picasso.Listener() {
        @Override
        public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
            Log.e("Picasso", "Failure for "   uri.toString(), exception);
        }
    });

    Picasso.setSingletonInstance(builder.build());
  

Теперь нам больше не нужно разрешать URL-адреса хранилища firebase в вашем адаптере. Перед выполнением запроса на загрузку мы отменим все ожидающие запросы к нему, ImageView а затем загрузим uri firebase следующим образом,

     //inside your onBindViewHolder method

    Picasso.with(context).cancelRequest(imageViewInstance);
    Picasso.with(context)
            .load("gs://somefirebase/imagefile")
            .into(imageViewInstance);
  

а Пикассо справится с остальным.