使用RealmChangeListener检查null

时间:2017-02-08 19:20:02

标签: android fragment realm realm-list

当RealmList为null时,我的应用程序崩溃了。它工作正常,直到我将我的模拟器从API 23更改为API 19.

我已经做过检查但不是,但仍然会崩溃。我试过这个

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)

1 个答案:

答案 0 :(得分:2)

您应该将RealmChangeListener添加到onCreateView()而不是onCreate()的Realm实例中,并在onDestroyView()中将其删除。

因为目前如果调用onDestroyView()并且尚未调用onDestroy(),那么如果有对域的写入,那么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未初始化,但如果存在对该域的写入,则RealmChangeListener将尝试更新未初始化的mAdapter这将导致你的崩溃。

解决方案:将null检查添加到RealmChangeListener

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