当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)
答案 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());
}
}
};