Вы не можете начать загрузку уничтоженной активности в относительном макете изображения, используя glide
Я использую относительную разметку для установки изображения. Почему я не использовал средства просмотра изображений, внутри относительной разметки я устанавливаю значки.
Я не знаю, в чем проблема именно в Glide. Я разместил трассировку стека и соответствующий код ниже:
Logcat:
FATAL EXCEPTION: main
Process: com.app.steve, PID: 15928
java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:134)
at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:102)
at com.bumptech.glide.Glide.with(Glide.java:644)
at com.app.steve.TabMorePagesDetailActivity$allPageDetails.onPostExecute(TabMorePagesDetailActivity.java:1050)
at com.app.steve.TabMorePagesDetailActivity$allPageDetails.onPostExecute(TabMorePagesDetailActivity.java:885)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
TabMorePagesDetailActivity.java:
RelativeLayout rlPageCoverImg;
rlPageCoverImg = (RelativeLayout)findViewById(R.id.rl_club_cover_img);
@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
dialog.dismiss();
............
String coverIMGurl = cover_avatar_obj.getString("url");
Log.e("ImgURL", coverIMGurl);
Glide.with(TabMorePagesDetailActivity.this).load(coverIMGurl).asBitmap().signature(new StringSignature(String.valueOf(System.currentTimeMillis())))
.into(new SimpleTarget<Bitmap>(500, 500) {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
Drawable drawable = new BitmapDrawable(getResources(), resource);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
rlPageCoverImg.setBackground(drawable);
}
}
});
}else {
rlPageCoverImg.setBackgroundResource(R.drawable.bg_golive);
}
@Override
protected void onDestroy()
{
super.onDestroy();
Glide.clear(rlPageCoverImg);
}
layout.xml:
<RelativeLayout
android:id="@+id/rl_club_cover_img"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@drawable/cancel_image" >
// Inside this relativelayout image, I'm using buttons and icons
</RelativeLayout>
15 ответов
Использование:
Glide.with(getApplicationContext()).load(...)
Вместо:
Glide.with(TabMorePagesDetailActivity.this).load(...)
Надеюсь, это решит вашу проблему ~
Вдохновленный из GitHub нити, я использую это перед загрузкой любого изображения
final Context context = getContext();
if (isValidContextForGlide(context) {
// Load image via Glide lib using context
}
public static boolean isValidContextForGlide(final Context context) {
if (context == null) {
return false;
}
if (context instanceof Activity) {
final Activity activity = (Activity) context;
if (activity.isDestroyed() || activity.isFinishing()) {
return false;
}
}
return true;
}
Вы можете просто проверить, уничтожен ли контекст или нет вручную;
if (context == null) {
return
} else if (context !is Application) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (context is FragmentActivity) {
if ((context as FragmentActivity).isDestroyed) {
return
}
} else if (context is Activity) {
if ((context as Activity).isDestroyed) {
return
}
}
}
}
Это также может быть представлено как функция расширения Kotlin:
/**
* Return true if this [Context] is available.
* Availability is defined as the following:
* + [Context] is not null
* + [Context] is not destroyed (tested with [FragmentActivity.isDestroyed] or [Activity.isDestroyed])
*/
fun Context?.isAvailable(): Boolean {
if (this == null) {
return false
} else if (this !is Application) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (this is FragmentActivity) {
return !this.isDestroyed
} else if (this is Activity) {
return !this.isDestroyed
}
}
}
return true
}
Пожалуйста, не используйте Glide.with(getApplicationContext())
если вам это действительно не нужно, по причинам, обсуждаемым здесь: скользящая загрузка изображения с контекстом приложения
Правильный ответ изложен здесь: https://github.com/bumptech/glide/issues/1484
В Kotlin это можно записать как функцию расширения:
fun Context.isValidGlideContext() = this !is Activity || (!this.isDestroyed && !this.isFinishing)
У меня возникла та же проблема за несколько дней. Я решил эту проблему, передав имя памяти контекста приложения от имени памяти контекста текущего класса.
Может быть, это поможет вам:-
используйте этот код
Glide.with(getApplicationContext())
.load(coverIMGurl)
.asBitmap()
.signature(new StringSignature(String.valueOf(System.currentTimeMillis())))
.into(new SimpleTarget<Bitmap>(500, 500) {....}
Даже если вы столкнулись с этой проблемой, внимательно прочитайте эту статью " https://github.com/bumptech/glide/issues/1097".
Обзор этой проблемы: это проблема библиотеки Glide.
Попробуйте это, прежде чем загружать ваше изображение с Glide, в моем случае mirefer - это StorageReference, miimagen - это ImageView. Я решил эту проблему, с этим. Я надеюсь, что это может помочь вам.
if (!this.isFinishing ()) {
// Load the image using Glide
Glide.with(YourActivity.this)
.using(new FirebaseImageLoader())
.load(mirefer)
.into(miimagen);
}
В действии используйте Gliide.with(getApplicatonContext()), а в адаптере используйте Glide.with(myContext.getApplicatonContext ())
// У меня работает нормально.
// для адаптера
Context myContext;
// также инициализируем в oncreateViewHolder
@Override
public MessagesHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_messages_layout, parent, false);
myContext = parent.getContext();
return new MessagesHolder(view);
}
Настройте Glide с параметром, который имеет правильный жизненный цикл. Например: использовать Glide.with(this)
вместо Glide.with(getContext())
в пользовательском представлении.
Не просто используйте контекст в адаптере, который вы берете из активности как context = this, а используйте context.getApplicationContext();
Вот расширение Kotlin, которое объединяет несколько ответов выше - это , это и это :
/**
* Returns true when [Context] is unavailable or is about to become unavailable
*/
fun Context?.isDoomed(): Boolean = when (this) {
null -> true
is Application -> false
is Activity -> (this.isDestroyed or this.isFinishing)
else -> false
}
Пожалуйста, используйте Glide.with (Holder.itemView.getContext ()). Load ....... Это решило мою проблему ref https://github.com/bumptech/glide/issues/2690
Просто используйте этот вспомогательный класс:
/**
* @Lukas Niessen
*/
public class GlideUsus {
public static final String TAG = "GlideUsus";
public interface Interface {
void doIfValidContext(RequestManager requestManager);
}
public static void execute(Context context, GlideUsus.Interface action) {
if (isValidContextForGlide(context)) {
action.doIfValidContext(Glide.with(context));
} else {
// nothing
Log.v(TAG, "Loading image failed");
}
}
public static boolean isValidContextForGlide(final Context context) {
if (context == null) {
return false;
}
if (context instanceof Activity) {
final Activity activity = (Activity) context;
if (activity.isDestroyed() || activity.isFinishing()) {
return false;
}
}
return true;
}
}
Применение:
GlideUsus.execute(mContext, (a -> a.load(uri).into(image)));
Привет модель для фрагмента Контекст активности сохраняется, даже когда вы нажимаете кнопку "Назад" и выходите из программы. И вернитесь в программу, вам не нужно повторно оценивать контекст, потому что контекст статический
@Override
public void onBindViewHolder(@NonNull final viewholder viewholder, final int i) {
final Model_Post model_post = list.get(i);
Log.e(TAG, "onBindViewHolder: "+model_post.getImageurl());
Glide.with(MainActivity.activity)
.load(Uri.parse(model_post.getImageurl()))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(viewholder.itemsPostBinding.imgvItempost);
}
Вы должны сделать это в основной деятельности:
public static AppCompatActivity activity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = MainActivity.this;
}
Другой способ - проверить, уничтожено ли действие, а затем загрузить его в элемент пользовательского интерфейса.
if (!newActivty.isDestroyed()){
...
}