Ответ 1
Я просто переключился с CircleImageView на обычный ImageView, и он внезапно сработал.
При попытке Picasso во время выполнения onStart()
он обычно загружает изображение из Firebase, используя ссылку загрузки с консоли.
Но когда я пытаюсь загрузить изображение внутри метода StorageReference onSuccess
, он просто не будет работать.
Этот класс расширяет фрагмент:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_IN && resultCode == Activity.RESULT_OK) {
isGranted = true;
String path = FireStorage.retUID() + "/";
showIndProgress();
Uri uri = data.getData();
StorageReference childPathRef = FireStorage.storageRef.child(path + uri.getLastPathSegment());
childPathRef.putFile(uri)
.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()) {
Picasso.with(mContext).load(task.getResult().getDownloadUrl())
.into(profView);
Picasso.Builder build = new Picasso.Builder(mContext);
build.listener(new Picasso.Listener() {
@Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
Toast.makeText(mContext, "exception\n" + exception.toString(), Toast.LENGTH_SHORT).show();
}
});
progressDialog.dismiss();
} else {
//failed
}
}
});
}
}
Это мой экземпляр FirebaseStorage в другом классе:
public static FirebaseStorage storage = FirebaseStorage.getInstance();
public static StorageReference storageRef =
storage.getReferenceFromUrl("gs://myurl.appspot.com/");
манифеста:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Мой XML-макет:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@drawable/gcover"
android:id="@+id/relativeLayout">
<de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/profPhoto"
android:clickable="true"
android:layout_width="120dp"
android:layout_height="120dp"
android:padding="20dp"
android:src="@drawable/default_prof"
android:scaleType="centerCrop"
app:civ_border_color="@color/trans"
app:civ_border_width="2dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Моя инициализация просмотров:
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_prof, container, false);
profView = (CircleImageView) view.findViewById(R.id.profPhoto);
btn1 = (Button) view.findViewById(R.id.btn_1);
btn2 = (Button) view.findViewById(R.id.btn_2);
btn3 = (Button) view.findViewById(R.id.btn_3);
return view;
}
Я просто переключился с CircleImageView на обычный ImageView, и он внезапно сработал.
Обновление 2:
Пока код, который я опубликовал, работает для меня, вы указываете, что он не подходит для вас. В моем тесте не используется фрагмент, я не знаю, какую версию библиотек вы используете, теперь он знает, как добавляется фрагмент в макет и т.д. Существует слишком много возможных причин для эффективного отладки это на SO.
В качестве эксперимента вы можете попробовать использовать Glide и FirebaseUI для загрузки вместо Picasso. Код показан ниже и работает для меня. Поскольку загрузка осуществляется из ссылки на хранилище, а не URL-адреса, для этого подхода требуется доступ для чтения к хранилищу. Вам также нужно добавить эти строки в зависимости от сборки:
// FirebaseUI 2.0.1 is the version to use for Firebase SDK version 11.0.1
// SDK/Firebase version compatibility is important.
// See the FirebaseUI docs for a table of compatible versions.
compile 'com.firebaseui:firebase-ui-storage:2.0.1'
compile 'com.github.bumptech.glide:glide:3.8.0'
.
childPathRef.putFile(Uri.fromFile(file))
.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Upload: SUCCESS");
Glide.with(mContext)
.using(new FirebaseImageLoader())
.load(childPathRef)
.dontAnimate()
.listener(new RequestListener<StorageReference, GlideDrawable>() {
@Override
public boolean onException(Exception e, StorageReference model,
Target<GlideDrawable> target, boolean isFirstResource) {
Log.e(TAG, "Download: FAILED: ", e);
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource,
StorageReference model, Target<GlideDrawable> target,
boolean isFromMemoryCache, boolean isFirstResource) {
Log.d(TAG, "Download: SUCCESS");
return false;
}
})
.into(mCircleImageView);
} else {
Log.e(TAG, "Upload: FAILED: " + task.getException().getMessage());
}
}
});
Update:
Дополнительная отладка показала, что загрузка и загрузка были успешно завершены. Проблема заключалась в рендеринге загруженного изображения. Документация для CircleImageView указывает, что noFade()
необходимо использовать при загрузке из Picasso:
Если вы используете библиотеку загрузки изображений, такую как Picasso или Glide, вам нужно отключите их анимацию затухания, чтобы избежать перепутанных изображений. Для Пикассо используйте опцию
noFade()
, для использования GlidedontAnimate()
.
Было также обнаружено, что маленькие изображения были визуализированы, но большие изображения были отображены как черные. fit()
был добавлен, чтобы заставить Picasso изменить размер изображения.
Чтобы обнаружить успех и неудачу при загрузке, используйте прослушиватель завершения, а не только прослушиватель успеха, и протестируйте task.isSuccessful()
. Загрузка, вероятно, не выполняется из-за правил безопасности или недействительна StorageReference
:
StorageReference childPathRef = Class.storageRef.child(path + uri.getLastPathSegment());
childPathRef.putFile(uri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Upload: SUCCESS");
Picasso.with(mContext)
.load(task.getResult().getDownloadUrl())
.noFade()
.fit()
.into(profView, new Callback() {
@Override
public void onSuccess() {
Log.d(TAG, "Download: SUCCESS");
Toast.makeText(mContext, "download done" , Toast.LENGTH_SHORT).show(); }
@Override
public void onError() {
Log.d(TAG, "Download: FAILED");
}
});
Toast.makeText(mContext, "upload done" , Toast.LENGTH_SHORT).show();
} else {
Log.e(TAG, "Upload: FAILED: " + task.getException().getMessage());
}
progressDialog.dismiss();
}
});
Ограничения для de.hdodenhof.circleimageview.CircleImageView
Возможно, что в этой строке кода:
Picasso.with(mContext).load(task.getResult().getDownloadUrl())
.into(profView);
profView воссоздает с фрагментом, а Picasso.into(View view)
сохраняет ссылку недели для просмотра.
Из документов:
public void into (android.widget.ImageView target) Асинхронно выполняет запрос в указанный ImageView. Примечание. Этот метод сохраняет слабую ссылку на экземпляр ImageView и будет автоматически поддерживают рециркуляцию объектов.
Попробуйте использовать:
public void into(@NotNull ImageView target,
Callback callback)
Возможно, это конфликт с CircleImageView
.
Попробуйте изменить его с помощью ImageView или определите CircleImageView
как ImageView
.
Попробуйте:
ImageView profView = (ImageView) view.findViewById(R.id.profPhoto);