大家好,我是用Firebase解析A Books信息的,而我是在尝试将数据存储在Realm数据库中的,以便用户可以脱机访问数据
但是我每次都会有例外
我试图在stackoverflow和google中搜索此问题,但每次遇到此异常都没有得到很好的答案,因此我希望大家对这个问题有所帮助,在此先感谢您的宝贵时间< / p>
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.w4ma.soft.tamenly, PID: 28122
java.lang.NullPointerException: Attempt to invoke virtual method 'int io.realm.RealmResults.size()' on a null object reference
at com.w4ma.soft.tamenly.CategoryActivities.Models.BooksModel.BooksAdapter.getItemCount(BooksAdapter.java:213)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3722)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3527)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4082)
at android.view.View.layout(View.java:17663)
at android.view.ViewGroup.layout(ViewGroup.java:5577)
at com.baoyz.widget.PullRefreshLayout.onLayout(PullRefreshLayout.java:512)
at android.view.View.layout(View.java:17663)
at android.view.ViewGroup.layout(ViewGroup.java:5577)
at android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1858)
at android.view.View.layout(View.java:17663)
at android.view.ViewGroup.layout(ViewGroup.java:5577)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17663)
at android.view.ViewGroup.layout(ViewGroup.java:5577)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17663)
at android.view.ViewGroup.layout(ViewGroup.java:5577)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17663)
at android.view.ViewGroup.layout(ViewGroup.java:5577)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17663)
at android.view.ViewGroup.layout(ViewGroup.java:5577)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:730)
at android.view.View.layout(View.java:17663)
at android.view.ViewGroup.layout(ViewGroup.java:5577)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2383)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2105)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1291)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6396)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:876)
at android.view.Choreographer.doCallbacks(Choreographer.java:688)
at android.view.Choreographer.doFrame(Choreographer.java:623)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:862)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6221)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
I/DynamiteModule: Considering local module com.google.android.gms.flags:2 and remote module com.google.android.gms.flags:3
Selected remote version of com.google.android.gms.flags, version >= 3
V/FA: Not logging ad unit exposure. No active activity
Not logging ad exposure. No active activity
W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
W/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzal@8dcd42b
W/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzal@8dcd42b
D/FA: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=MainActivity, firebase_previous_id(_pi)=-8357801964819412298, firebase_screen_class(_sc)=BookActivity, firebase_screen_id(_si)=-8357801964819412282}]
W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
I/FirebaseAuth: [FirebaseAuth:] Loading module via FirebaseOptions.
[FirebaseAuth:] Preparing to create service connection to gms implementation
V/FA: Activity resumed, time: 275219039
E/CrashlyticsCore: Failed to execute task.
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:177)
at com.crashlytics.android.core.CrashlyticsBackgroundWorker.submitAndWait(CrashlyticsBackgroundWorker.java:41)
at com.crashlytics.android.core.CrashlyticsController.handleUncaughtException(CrashlyticsController.java:320)
at com.crashlytics.android.core.CrashlyticsController$6.onUncaughtException(CrashlyticsController.java:300)
at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler.uncaughtException(CrashlyticsUncaughtExceptionHandler.java:42)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1063)
at java.lang.Thread.dispatchUncaughtException(Thread.java:1979)
BookList.class
public class BookList extends RealmObject {
// @PrimaryKey
// private String realmID;
private String post_id;
private String post_title;
private String post_real_price;
private String currency;
private String post_description;
private String post_image;
private String post_datetime;
private String category;
// public String getRealmID() {
// return realmID;
// }
//
// public void setRealmID(String realmID) {
// this.realmID = realmID;
// }
public String getPost_id() {
return post_id;
}
public void setPost_id(String post_id) {
this.post_id = post_id;
}
public String getPost_title() {
return post_title;
}
public void setPost_title(String post_title) {
this.post_title = post_title;
}
public String getPost_real_price() {
return post_real_price;
}
public void setPost_real_price(String post_real_price) {
this.post_real_price = post_real_price;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getPost_description() {
return post_description;
}
public void setPost_description(String post_description) {
this.post_description = post_description;
}
public String getPost_image() {
return post_image;
}
public void setPost_image(String post_image) {
this.post_image = post_image;
}
public String getPost_datetime() {
return post_datetime;
}
public void setPost_datetime(String post_datetime) {
this.post_datetime = post_datetime;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_pp() {
return user_pp;
}
public void setUser_pp(String user_pp) {
this.user_pp = user_pp;
}
public String getUser_ID() {
return user_ID;
}
public void setUser_ID(String user_ID) {
this.user_ID = user_ID;
}
private String user_name;
private String user_pp;
private String user_ID;
public BookList( String post_id, String post_title, String post_real_price, String currency, String post_description, String post_image, String post_datetime, String category, String user_name, String user_pp, String user_ID) {
//this.realmID = realmID;
this.post_id = post_id;
this.post_title = post_title;
this.post_real_price = post_real_price;
this.currency = currency;
this.post_description = post_description;
this.post_image = post_image;
this.post_datetime = post_datetime;
this.category = category;
this.user_name = user_name;
this.user_pp = user_pp;
this.user_ID = user_ID;
}
public BookList() {
} //Constructer
}
BooksAdapter.class
public class BooksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public BooksAdapter(RealmResults<BookList> listy, Context mContext) {
this.listy = listy;
this.mContext = mContext;
}
RealmResults<BookList> listy;
TinyDB tinyDB;
Context mContext;
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == 12 ){
return new AdsViewHolder(LayoutInflater.from(mContext.getApplicationContext()).inflate(R.layout.bigadbanner,parent,false));
}else {
return new BooksViewHolder(LayoutInflater.from(mContext.getApplicationContext()).inflate(R.layout.row_item,parent,false));
}
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
tinyDB = new TinyDB(mContext);
final String country = tinyDB.getString("country");
int viewType = getItemViewType(position);
if (viewType == 12) {
AdsViewHolder adsHolder = (AdsViewHolder) holder;
AdRequest adRequest = new AdRequest.Builder().build();
adsHolder.BigBannerAdView.loadAd(adRequest);
adsHolder.BigBannerAdView.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
// Code to be executed when an ad finishes loading.
}
@Override
public void onAdFailedToLoad(int errorCode) {
// Code to be executed when an ad request fails.
Toasty.info(mContext, mContext.getString(R.string.disable_adblock), Toast.LENGTH_LONG).show();
}
@Override
public void onAdOpened() {
// Code to be executed when an ad opens an overlay that
// covers the screen.
}
@Override
public void onAdLeftApplication() {
// Code to be executed when the user has left the app.
}
@Override
public void onAdClosed() {
// Code to be executed when when the user is about to return
// to the app after tapping on an ad.
}
});
} else {
final BooksViewHolder BooksHolder = (BooksViewHolder) holder;
final BookList list = listy.get(position);
BooksHolder.PostTitle.setText(list.getPost_title());
BooksHolder.PostDate.setText(list.getPost_datetime());
Glide.with(mContext)
.load(list.getPost_image())
.into(BooksHolder.imgPostCover);
BooksHolder.UserProfileName.setText(list.getUser_name());
Picasso.get()
.load(list.getUser_pp())
.placeholder(R.drawable.user)
.into(BooksHolder.TheUserProfilePic);
BooksHolder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// When Clicking On the Post the app will send a UserID to the Server with generated Key
FirebaseUser mAuth = FirebaseAuth.getInstance().getCurrentUser();
String postID = list.getPost_id();
Intent intent = new Intent(mContext, ShowThePost.class);
intent.putExtra("post_ID", list.getPost_id());
intent.putExtra("post_Title", list.getPost_title());
intent.putExtra("post_Desc", list.getPost_description());
intent.putExtra("post_Image", list.getPost_image());
intent.putExtra("post_DateTime", list.getPost_datetime());
intent.putExtra("post_Price", list.getPost_real_price());
intent.putExtra("post_Currency", list.getCurrency());
intent.putExtra("post_UserName", list.getUser_name());
intent.putExtra("post_UserProfilePicture", list.getUser_pp());
intent.putExtra("category", list.getCategory());
intent.putExtra("userID", list.getUser_ID());
mContext.startActivity(intent);
String userName = mAuth.getDisplayName();
DatabaseReference dbViewCount = FirebaseDatabase.getInstance().getReference(country);
dbViewCount.child("Posts").child(postID).child("Views").push().setValue(userName);
}
});
//_______________________________________________________________________________________________
//Get Comments Count
final String category = list.getCategory();
final String postID = list.getPost_id();
DatabaseReference dbCommentsCount = FirebaseDatabase.getInstance().getReference(country).child("Posts");
dbCommentsCount.child(category).child(postID).child("Comments").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
long CommentsCount = dataSnapshot.getChildrenCount();
BooksHolder.txtCountComments.setText(String.valueOf(CommentsCount));
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toasty.error(mContext, databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
//=========================================================================================
//get Views Count
DatabaseReference dbViewsCount = FirebaseDatabase.getInstance().getReference(country).child("Posts");
dbViewsCount.child(category).child(postID).child("Views").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
long ViewsCount = dataSnapshot.getChildrenCount();
BooksHolder.txtCountViews.setText(String.valueOf(ViewsCount));
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toasty.error(mContext, databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
//------------------------------------------------------------------------------------------------------
}
}
@Override
public int getItemViewType(int position) {
if (position == 3) {
return 12;
} else {
return super.getItemViewType(position);
}
}
@Override
public int getItemCount() {
return listy.size();
}
public class BooksViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.TheuserProfilePicture)
CircularImageView TheUserProfilePic;
@BindView(R.id.userName)
TextView UserProfileName;
@BindView(R.id.imgPostShow)
RoundedImageView imgPostCover;
@BindView(R.id.postTitle)
TextView PostTitle;
@BindView(R.id.txt_Post_Date)
TextView PostDate;
@BindView(R.id.GotoPostItem)
MaterialRippleLayout linearLayout;
@BindView(R.id.txtCountViews)
TextView txtCountViews;
@BindView(R.id.txtCountComments)
TextView txtCountComments;
public BooksViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
public class AdsViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.BigBannerAdView)
AdView BigBannerAdView;
public AdsViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
BooksActivity.class,这是应该在其中查看数据的活动 Recyclerview
public class BookActivity extends AppCompatActivity {
@Override
protected void onDestroy() {
super.onDestroy();
realm.close();
}
@Override
protected void onPause() {
super.onPause();
}
private static final String TAG = "TAG";
@BindView(R.id.Postgo) FloatingActionButton floatingActionButton;
@BindView(R.id.main_swipe)
PullRefreshLayout waveSwipeRefreshLayout;
@BindView(R.id.recyclerBooks) RecyclerView rcBooks;
BooksAdapter adapter;
DatabaseReference dbref;
RealmResults<BookList> list;
TinyDB tinyDB;
Realm realm;
@Deprecated
ProgressDialog dialog;
@Override
public void onBackPressed() {
super.onBackPressed();
CustomIntent.customType(this,"right-to-left");
finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_books);
ButterKnife.bind(this);
Realm.getDefaultInstance();
tinyDB = new TinyDB(this);
Refreshing();
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(BookActivity.this,CreatePostActivity.class);
intent.putExtra("name","Books");
startActivity(intent);
}
});
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
rcBooks.setLayoutManager(linearLayoutManager);
rcBooks.setHasFixedSize(true);
rcBooks.smoothScrollToPosition(0);
rcBooks.setItemAnimator(new DefaultItemAnimator());
try {
retriveData();
list = realm.where(BookList.class).findAllAsync().sort("realmID", Sort.DESCENDING);
} catch (Exception e) {
Crashlytics.logException(e);
Toasty.error(BookActivity.this,getString(R.string.exception_code) + e.getMessage() ,Toast.LENGTH_LONG).show();
Log.d(TAG, "onRetriveData: " + e.getMessage());
}
}
public void retriveData() {
String country = tinyDB.getString("country");
if (country != null || !country.isEmpty()) {
dbref = FirebaseDatabase.getInstance().getReference(country).child("Posts");
dbref.keepSynced(true);
dbref.child("Books").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dtSnapshot : dataSnapshot.getChildren()) {
if (!dataSnapshot.hasChildren()) {
Toasty.info(BookActivity.this, getString(R.string.no_more_posts), Toast.LENGTH_SHORT).show();
} else {
BookList modelList = dtSnapshot.getValue(BookList.class);
// modelList.setRealmID(String.valueOf(NextKey()));
realm.beginTransaction();
realm.copyToRealmOrUpdate(modelList);
realm.commitTransaction();
realm.close();
Log.d(TAG, "onDataChange: " + modelList);
adapter.notifyDataSetChanged();
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(BookActivity.this, getString(R.string.something_went_wrong) + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
adapter = new BooksAdapter(list,BookActivity.this);
final SkeletonScreen skeletonScreen = Skeleton.bind(rcBooks)
.adapter(adapter)
.shimmer(true)
.angle(20)
.frozen(false)
.duration(1000)
.count(10)
.load(R.layout.comment_row)
.show(); //default count is 10
skeletonScreen.hide();
waveSwipeRefreshLayout.setRefreshing(false);
}else {
Toasty.error(BookActivity.this,getString(R.string.error_code_b16) ,Toast.LENGTH_LONG).show();
}
}
public void Refreshing(){
waveSwipeRefreshLayout.setOnRefreshListener(new PullRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retriveData();
}
});
}
public int NextKey(){
try {
return realm.where(BookList.class).max("realmID").intValue() + 1;
} catch (ArrayIndexOutOfBoundsException | NullPointerException e ) {
return 0;
}
}
}
答案 0 :(得分:0)
在您的retriveData()
方法中,您正在创建BooksAdapter
的新实例,如下所示:
adapter = new BooksAdapter(list,BookActivity.this);
您正在将list
的值传递给此新实例。问题在于,当调用retriveData()
时,尚未分配list
,即null
。您的retriveData()
方法在传递之前没有分配list
,因此它传递的是null
值。您仅在呼叫list
后分配retriveData()
:
retriveData();
list = realm.where(BookList.class).findAllAsync().sort("realmID", Sort.DESCENDING);
所以您在这里得到NullPointerException
public int getItemCount() {
return listy.size();
}
尝试在null
对象引用上调用方法。
一种解决方案是在实例化list
之前分配BooksAdapter
。
为帮助您在代码中发现这些类型的问题,请考虑对预期不会成为@NonNull
的变量使用null
批注:
@NonNull
RealmResults<BookList> listy;
这将为您指出null
值的问题,否则您可能会忽略它们。了解有关注释here的更多信息。
您的代码的另一个问题是:
Realm.getDefaultInstance();
此处,返回的Realm
实例未分配任何内容。您显然打算将其分配给realm
。因此,realm
也是null
。更改为:
realm = Realm.getDefaultInstance();