2017-02-08 7 views
0

Мое приложение вылетает, когда RealmList равно null. Он работал нормально, пока я не сменил эмулятор от API 23 до API 19.Проверка на null с помощью RealmChangeListener

Я уже проверил, но его нет, но все равно возникают сбои. Я пытался делать этого

RealmChangeListener realmChangeListener = new RealmChangeListener() { 
@Override 
public void onChange(Object element) { 
    if(getPostsFromDb() != null){ 
     mAdapter.swapData(getPostsFromDb());  
    } 
    } 
}; 

Приложение все еще врезаться с NPE

Как я решить эту проблему?

public class CartFragment extends Fragment{ 

private Realm realm; 

private RecyclerView mRecyclerView; 
private BucketFragmentAdapter mAdapter; 
private RecyclerView.LayoutManager mLayoutManager; 

private ProgressBar circularProgessBar; 

private RelativeLayout emptyView; 

RealmChangeListener realmChangeListener = new RealmChangeListener() { 
    @Override 
    public void onChange(Object element) { 
     mAdapter.swapData(getPostsFromDb()); 
    } 
}; 

@Override 
public void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    realm = Realm.getDefaultInstance(); 
    int user_id = Utils.getStoredUser(getActivity()).getId(); 

    BucketListAPIHelper.loadBucket(user_id); 

     realm.addChangeListener(realmChangeListener); 
} 

public View onCreateView(LayoutInflater inflater, ViewGroup vg, 
         Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.cart_fragment, vg, false); 

    emptyView = (RelativeLayout) view.findViewById(R.id.empty_view); 

    circularProgessBar = (ProgressBar) view.findViewById(R.id.circular_progress_bar); 

    circularProgessBar.setVisibility(View.VISIBLE); 

    if(isNetworkConnected()){ 
     circularProgessBar.setVisibility(View.GONE); 
    }else{ 
     new AlertDialog.Builder(getActivity()) 
       .setTitle("No Internet Connection") 
       .setMessage("It looks like your a problem with your internet connection. Please turn it " + 
         "on and try again") 
       .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
        } 
       }).setIcon(android.R.drawable.ic_dialog_alert).show(); 
    } 

    loadBucket(view); 

    return view; 
} 


private void loadBucket(View view) { 

    RealmResults<Bucket> realmResults = getPostsFromDb(); 

    mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); 
    mRecyclerView.setHasFixedSize(true); 
    mLayoutManager = new LinearLayoutManager(getActivity()); 
    mRecyclerView.setLayoutManager(mLayoutManager); 

    if(!realmResults.isEmpty()){ 
     mRecyclerView.setVisibility(View.VISIBLE); 
     emptyView.setVisibility(View.GONE); 
     circularProgessBar.setVisibility(View.GONE); 
     mAdapter = new BucketFragmentAdapter(realmResults, getActivity(), true); 
     mRecyclerView.setAdapter(mAdapter); 

    }else{ 
     mRecyclerView.setVisibility(View.GONE); 
     emptyView.setVisibility(View.VISIBLE); 
    } 

} 


@Subscribe 
public void onPostSuccess(BucketListAPIHelper.PostsInfoSuccess postInfo) { 
    //setRefreshing(false); 
} 

public RealmResults<Bucket> getPostsFromDb() { 
    RealmResults<Bucket> realmResults = realm.where(Bucket.class).findAll(); 
    if(realmResults != null){ 
     return realmResults; 
    } 
    return realmResults; 
} 

/* Present user with some error message when there's an issue while retrieving data */ 
@Subscribe 
public void onPostFailure(BucketListAPIHelper.PostsInfoFailure error) { 
    ///setRefreshing(false); 
    //displaySimpleConfirmSnackBar(recyclerView, error.getErrorMessage()); 
} 


private boolean isNetworkConnected() { 
    ConnectivityManager connMgr = (ConnectivityManager) 
      getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); // 1 
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); // 2 
    return networkInfo != null && networkInfo.isConnected(); // 3 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    EventBusSingleton.unregister(this); 

} 

@Override 
public void onResume() { 
    super.onResume(); 
    EventBusSingleton.register(this); 
} 

@Override 
public void onDestroy() { 

    if (realm != null) { 
     realm.close(); 
    } 

    super.onDestroy(); 
} 

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    } 

} 

Трассировка стека

02-08 14:19:58.526 23440-23440/ng.aswitch.shoppar E/dalvikvm: Could not   find class 'android.graphics.drawable.RippleDrawable', referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering 
    02-08 14:24:27.126 23440-23440/ng.aswitch.shoppar E/AndroidRuntime: FATAL EXCEPTION: main 
Process: ng.aswitch.shoppar, PID: 23440 
java.lang.NullPointerException 
    at ng.aswitch.shoppar.fragments.CartFragment$1.onChange(CartFragment.java:66) 
    at io.realm.HandlerController.notifyGlobalListeners(HandlerController.java:248) 
    at io.realm.HandlerController.notifyAllListeners(HandlerController.java:323) 
    at io.realm.HandlerController.realmChanged(HandlerController.java:456) 
    at io.realm.HandlerController.handleMessage(HandlerController.java:122) 
    at android.os.Handler.dispatchMessage(Handler.java:98) 
    at android.os.Looper.loop(Looper.java:136) 
    at android.app.ActivityThread.main(ActivityThread.java:5017) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
    at  dalvik.system.NativeStart.main(Native Method) 
+0

, что является трассировка стека – EpicPandaForce

+0

@EpicPandaForce я обновил вопрос и добавил трассировки стека – SimpiMind

ответ

2

Вы должны добавить RealmChangeListener к примеру Realm в onCreateView() вместо onCreate(), а также удалить его в onDestroyView().

Поскольку в настоящее время, если onDestroyView() называется, и onDestroy() пока не называются, а затем, если есть запись в Realm, то RealmChangeListener будет пытаться не обновлять mAdapter даже если вид больше не существует.


Хотя я думаю, что ваша реальная проблема исходит из того, что

if(!realmResults.isEmpty()){ 
    mRecyclerView.setVisibility(View.VISIBLE); 
    emptyView.setVisibility(View.GONE); 
    circularProgessBar.setVisibility(View.GONE); 
    mAdapter = new BucketFragmentAdapter(realmResults, getActivity(), true); 
    mRecyclerView.setAdapter(mAdapter); 

}else{ 
    mRecyclerView.setVisibility(View.GONE); 
    emptyView.setVisibility(View.VISIBLE); 
} 

если RealmResults пусто, то mAdapter не инициализирован, но если есть запись в Realm, то RealmChangeListener будет пытаться для обновления не инициализированного mAdapter, который приведет к вашему сбою.


Решение: добавить null чек RealmChangeListener вокруг mAdapter

RealmChangeListener realmChangeListener = new RealmChangeListener() { 
    @Override 
    public void onChange(Object element) { 
     if(mAdapter != null) { 
      mAdapter.swapData(getPostsFromDb()); 
     } 
    } 
}; 
+0

Он работал, спасибо большое. Тем не менее, поведение изменилось, и мой фрагмент обновляется немедленно, как и раньше, до тех пор, пока я не оставлю фрагмент другому фрагменту и не вернусь к фрагменту перед его обновлением. – SimpiMind

+0

вызывать 'BucketListAPIHelper.loadBucket (user_id);' in 'onCreateView()' или 'onViewCreated()' – EpicPandaForce

+0

Я пробовал оба, все еще не работая, до и уезжать и возвращаться к фрагменту. Фрагмент только обновляет сам, если я, вероятно, удалить и элемент в списке или удалить весь список внутри этого фрагмента. – SimpiMind

Смежные вопросы