在运行时onStart()
方法上尝试Picasso时,它通常使用控制台中的下载链接从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;
}
答案 0 :(得分:10)
更新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());
}
}
});
<强>更新强>
其他调试显示上传和下载均已成功完成。问题在于渲染下载的图像。 documentation for CircleImageView表示从毕加索下载时必须使用noFade()
:
如果您使用像Picasso或Glide这样的图像加载库,则需要 禁用他们的淡入淡出动画以避免混乱的图像。毕加索 使用
noFade()
选项,对于Glide使用dontAnimate()
。
还发现渲染了小图像,但是大图像显示为黑色。添加了fit()
以使Picasso调整图像大小。
要检测上传成功和失败,请使用completion listener而不仅仅是成功侦听器,并测试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();
}
});
答案 1 :(得分:2)
de.hdodenhof.circleimageview.CircleImageView
的限制答案 2 :(得分:1)
可能在这行代码中:
Picasso.with(mContext).load(task.getResult().getDownloadUrl())
.into(profView);
profView正在使用片段重新创建,Picasso.into(View view)
保持周参考视图。
来自docs:
public void into(android.widget.ImageView target)异步 满足指定ImageView的请求。注意:此方法 保持对ImageView实例的弱引用 自动支持对象回收。
尝试使用:
public void into(@NotNull ImageView target,
Callback callback)
答案 3 :(得分:1)
我刚刚从 CircleImageView 切换到正常的 ImageView ,它突然发挥作用。
答案 4 :(得分:0)
可能与CircleImageView
发生冲突。
尝试使用ImageView进行更改,或将CircleImageView
定义为ImageView
。
尝试:
ImageView profView = (ImageView) view.findViewById(R.id.profPhoto);