Reputation: 965
I am using FragmentStatePagerAdapter to show around 5 fragments in an activity.On each activity I am showing the images which I am fetching from FirebaseListAdapter/FirebaseRecyclerAdapter. As it is FragmentStagePagerAdapter adjacent views/Fragments will be initialized even they are not visible.If the tabs are scrolled in a fast manner (forward/backward) App is crashing with above mentioned error.I found out some similar issues on the internet but not able to fix this issue.I am also getting You cannot start a load for a destroyed activity error if I am starting a new activity(In activity I am showing images from firebase in a grid view) and closing it immediately(pressing the back button) I am using following code.
adapt= new FirebaseListAdapter<MyClassStudent>(getActivity(), MyClassStudent.class, R.layout.mychild_grid_template, myRef) {
@Override
protected void populateView(final View v, MyClassStudent model, int position) {
final TextView uname = (TextView) v.findViewById(R.id.mychild_uname);
final CircleImageView profileImage=(CircleImageView)v.findViewById(R.id.mychild_image);
studRef.child(model.getUsername()).addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
Child child=dataSnapshot.getValue(Child.class);
uname.setText(child.getUsername());
Glide.with(getActivity()).load(child.getProfileImage()).into(profileImage);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
};
Stack Trace:
E/UncaughtException: java.lang.NullPointerException: You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null (which usually occurs when getActivity() is called before the Fragment is attached or after the Fragment is destroyed).
at com.bumptech.glide.util.Preconditions.checkNotNull(Preconditions.java:27)
at com.bumptech.glide.Glide.getRetriever(Glide.java:509)
at com.bumptech.glide.Glide.with(Glide.java:563)
at com.mycompany.educareteacher.FragmentStudents$2$1.onDataChange(FragmentStudents.java:184)
at com.google.firebase.database.zzp.onDataChange(Unknown Source)
at com.google.android.gms.internal.tl.zza(Unknown Source)
at com.google.android.gms.internal.vg.zzHW(Unknown Source)
at com.google.android.gms.internal.vm.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5438)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
D/FA: Logging event (FE): app_exception(_ae), Bundle[{firebase_event_origin(_o)=crash, firebase_screen_class(_sc)=ClassDetailActivity, firebase_screen_id(_si)=-4663411025690523798, timestamp=1500710706898, fatal=1}]
V/FA: Recording user engagement, ms: 3544
D/FA: Logging event (FE): user_engagement(_e), Bundle[{firebase_event_origin(_o)=auto, engagement_time_msec(_et)=3544, firebase_screen_class(_sc)=ClassDetailActivity, firebase_screen_id(_si)=-4663411025690523798}]
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mycompany.com.educareteacher, PID: 5154
java.lang.NullPointerException: You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null (which usually occurs when getActivity() is called before the Fragment is attached or after the Fragment is destroyed).
at com.bumptech.glide.util.Preconditions.checkNotNull(Preconditions.java:27)
at com.bumptech.glide.Glide.getRetriever(Glide.java:509)
at com.bumptech.glide.Glide.with(Glide.java:563)
at com.mycompany.educareteacher.FragmentStudents$2$1.onDataChange(FragmentStudents.java:184)
at com.google.firebase.database.zzp.onDataChange(Unknown Source)
at com.google.android.gms.internal.tl.zza(Unknown Source)
at com.google.android.gms.internal.vg.zzHW(Unknown Source)
at com.google.android.gms.internal.vm.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5438)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
How Can I solve this issue?
Upvotes: 4
Views: 18980
Reputation: 194
I'm solved this issue. add below code in onBindViewHolder inside
context = holder.itemView.getContext();
Example
@Override
protected void onBindViewHolder(@NonNull NoteHolder holder, int position, @NonNull final Note model) {
context = holder.itemView.getContext();
Glide.with(context).load(model.getImage()).into(holder.r_iv);
}
Upvotes: 0
Reputation: 318
This problem arise when you miss to add context in the constructor of a adapter and you can easily solve it :-)
Do not forget to add this.context = context in the constructor
public groupUserAdapter(Context context, ArrayList<Users> groupUsers) {
this.groupUsers = groupUsers;
this.context = context;
};
Upvotes: 0
Reputation: 1
in fragment just use.
if (getActivity != null) {
Glide.with(getActivity()).load(imageUrl).into(yourImageView);
}
Upvotes: 0
Reputation: 11
ArrayList<ClientData> clientData = new ArrayList<>();
int j=0;
for (String h:profileImg)
{
ClientData clientItem = new ClientData();
clientItem.setProfileImage(h);
clientItem.setName(name[j]);
clientItem.setAddress(location[j]);
clientData.add(clientItem);
j++;
}
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplication(),RecyclerView.VERTICAL,false);
recy_client.setLayoutManager(layoutManager);
recy_client.setItemAnimator(new DefaultItemAnimator());
clientAdp = new ClientAdp(getApplicationContext(),clientData);
recy_client.setAdapter(clientAdp);
Replace From
clientAdp = new ClientAdp(context,clientData);
To
clientAdp = new ClientAdp(getApplicationContext(),clientData);
in my case
Upvotes: -1
Reputation: 456
I Found this way too
public class NoteAdapter extends FirestoreRecyclerAdapter<Note,NoteAdapter.NoteHolder> {
Context context;
public NoteAdapter(@NonNull FirestoreRecyclerOptions<Note> options) {
super(options);
}
@Override
protected void onBindViewHolder(@NonNull NoteHolder holder, int position, @NonNull final Note model) {
context = holder.itemView.getContext();
holder.r_tv.setText(model.getTitle());
Glide.with(context).load(model.getImage()).into(holder.r_iv);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(context, CategoryProductActivity.class);
MainActivity.myCategory2 = model.getTitle();
MainActivity.myCategoryIcon2 = model.getImage();
context.startActivity(i);
}
});
}
@NonNull
@Override
public NoteHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_category,parent,false);
return new NoteHolder(v);
}
public static class NoteHolder extends RecyclerView.ViewHolder
{
TextView r_tv;
ImageView r_iv;
public NoteHolder(@NonNull View itemView) {
super(itemView);
r_tv = itemView.findViewById(R.id.r_tv);
r_iv = itemView.findViewById(R.id.r_iv);
}
}
}
Upvotes: 3
Reputation: 456
Add Below Code on Activity on which RecyclerView is present
public static Context context;
Then in onCreate
of the same Activity on which RecyclerView is present add below Code
context = getApplicationContext();
then take reference to glide as shown below
Glide.with(YourActivity.context).load("Image Link").into(holder.YourImageView);
Upvotes: 1
Reputation: 2985
I prefer using isAdded() method of fragment before loading image with Glide.
Upvotes: 5
Reputation: 11622
Your fragment is detached before response coming from firebase, So try to check getActivity()
null before using that
public void onDataChange(DataSnapshot dataSnapshot) {
if (getActivity() == null) {
return;
}
Child child = dataSnapshot.getValue(Child.class);
uname.setText(child.getUsername());
Glide.with(getActivity()).load(child.getProfileImage()).into(profileImage);
}
You can do like to check activity is null or not in other place.
private Activity mActivity;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = getActivity();
}
@Override
public void onDetach() {
super.onDetach();
mActivity = null;
}
private void doAction() {
if (mActivity == null) {
return;
}
adapt = new FirebaseListAdapter<MyClassStudent>(mActivity, MyClassStudent.class, R.layout.mychild_grid_template, myRef) {
@Override
protected void populateView(final View v, MyClassStudent model, int position) {
final TextView uname = (TextView) v.findViewById(R.id.mychild_uname);
final CircleImageView profileImage = (CircleImageView) v.findViewById(R.id.mychild_image);
studRef.child(model.getUsername()).addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
if (mActivity == null) {
return;
}
Child child = dataSnapshot.getValue(Child.class);
uname.setText(child.getUsername());
Glide.with(mActivity).load(child.getProfileImage()).into(profileImage);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
};
}
Upvotes: 10