您无法在未连接的视图或片段上启动加载,其中getActivity()返回空值

问题描述:

我正在使用FragmentStatePagerAdapter在活动中显示5个片段。在每个活动中,我显示的是从FirebaseListAdapter/FirebaseRecyclerAdapter。因为它是FragmentStagePagerAdapter相邻的视图/片段将被初始化,即使它们不可见。如果标签以快速方式滚动(向前/向后),应用程序崩溃与上述错误。我发现了一些类似的问题在互联网上,但没有能够解决此问题。我也越来越如果我开始一个新的活动(在活动中,我在网格视图中显示来自Firebase的图像)并立即关闭它(按下按钮),您无法为已销毁的活动启动加载错误后退按钮) 我正在使用以下代码。您无法在未连接的视图或片段上启动加载,其中getActivity()返回空值

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) { 

        } 
       }); 
      } 
     }; 

堆栈跟踪:

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) 

我怎样才能解决这个问题?

您的片段响应从火力点来之前分离,所以尽量使用

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); 
} 

你可以这样做检查活动为空或不是在别的地方之前检查getActivity()空。

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) { 

       } 
      }); 
     } 
    }; 
} 

我更喜欢在使用Glide加载图像之前使用isAdded()片段的方法。