问题
My app crashes when I sign in. The issue stems from the load function. when it initiates the adapter.startListening();
I am not sure if it is from versions conflict or otherwise. please help
My logcat:
FATAL EXCEPTION: main
Process: abcd.com.eatme, PID: 10687
java.lang.RuntimeException: Unable to start activity ComponentInfo
{abcd.com.eatme/abcd.com.eatme.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.firebase.ui.database.FirebaseRecyclerAdapter.startListening()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3319)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
at android.app.ActivityThread.access$1100(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.firebase.ui.database.FirebaseRecyclerAdapter.startListening()' on a null object reference
at abcd.com.eatme.MainActivity.onStart(MainActivity.java:55)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1266)
at android.app.Activity.performStart(Activity.java:6943)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3276)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
at android.app.ActivityThread.access$1100(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
My Home class is
public class Home extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
FirebaseDatabase database;
DatabaseReference category;
TextView textFullName;
FirebaseRecyclerAdapter adapter;
RecyclerView recycler_menu;
RecyclerView.LayoutManager layoutManager;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
setContentView ( R.layout.activity_home );
Toolbar toolbar = (Toolbar) findViewById ( R.id.toolbar );
toolbar.setTitle ( "Menu" );
setSupportActionBar ( toolbar );
//initiate firebase
database = FirebaseDatabase.getInstance ();
category = database.getReference ("Category");
FloatingActionButton fab = (FloatingActionButton) findViewById ( R.id.fab );
fab.setOnClickListener ( new View.OnClickListener () {
@Override
public void onClick (View view) {
Snackbar.make ( view, "Replace with your own action", Snackbar.LENGTH_LONG )
.setAction ( "Action", null ).show ();
}
} );
DrawerLayout drawer = (DrawerLayout) findViewById ( R.id.drawer_layout );
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle (
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close );
drawer.addDrawerListener ( toggle );
toggle.syncState ();
NavigationView navigationView = (NavigationView) findViewById ( R.id.nav_view );
navigationView.setNavigationItemSelectedListener ( this );
//set name for user
View headerView = navigationView.getHeaderView ( 0 );
textFullName = (TextView) headerView.findViewById ( R.id.textFullName );
textFullName.setText ( Common.currentUser.getName () );
//load menu
recycler_menu =(RecyclerView) findViewById ( R.id.recycler_menu );
recycler_menu.setHasFixedSize ( true );
layoutManager = new LinearLayoutManager ( this );
recycler_menu.setLayoutManager ( layoutManager );
loadMenu();`enter code here`
}
private void loadMenu(){
Query query = FirebaseDatabase
.getInstance()
.getReference()
.child("Category");
FirebaseRecyclerOptions<Category> options =
new FirebaseRecyclerOptions.Builder<Category>()
.setQuery(query, Category.class)
.build();
adapter = new FirebaseRecyclerAdapter<Category, MenuViewHolder>(options) {
@Override
public MenuViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.menu_item, parent, false);
return new MenuViewHolder(view);
}
@Override
protected void onBindViewHolder(@NonNull MenuViewHolder holder, int position, @NonNull Category model) {
holder.textMenuName.setText(model.getName());
Picasso.with(getBaseContext()).load(model.getImage())
.into(holder.imageView);
final Category clickItem = model;
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onClick(View view, int position, boolean isLongClick) {
Toast.makeText(Home.this, ""+clickItem.getName(), Toast.LENGTH_SHORT).show();
}
});
}
};
recycler_menu.setAdapter(adapter);
}
@Override
public void onBackPressed () {
DrawerLayout drawer = (DrawerLayout) findViewById ( R.id.drawer_layout );
if (drawer.isDrawerOpen ( GravityCompat.START )) {
drawer.closeDrawer ( GravityCompat.START );
} else {
super.onBackPressed ();
}
}
@Override
public boolean onCreateOptionsMenu (Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater ().inflate ( R.menu.home, menu );
return true;
}
@Override
public boolean onOptionsItemSelected (MenuItem item) {
return super.onOptionsItemSelected ( item );
}
@SuppressWarnings ("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected (MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId ();
if (id == R.id.nav_menu) {
// Handle the camera action
} else if (id == R.id.nav_cart) {
} else if (id == R.id.nav_orders) {
} else if (id == R.id.nav_logout) {
}
DrawerLayout drawer = (DrawerLayout) findViewById ( R.id.drawer_layout );
drawer.closeDrawer ( GravityCompat.START );
return true;
}
}
My MainActivity class
public class MainActivity extends AppCompatActivity {
Button btnSignUp, btnSignIn;
TextView textSlogan;
FirebaseRecyclerAdapter adapter;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
setContentView ( R.layout.activity_main );
btnSignIn = (Button) findViewById ( R.id.btnSignIn );
btnSignUp = (Button) findViewById ( R.id.btnSignUp );
textSlogan = (TextView) findViewById ( R.id.textSlogan );
Typeface face = Typeface.createFromAsset ( getAssets (),"font/NABILA.TTF" );
textSlogan.setTypeface ( face);
btnSignUp.setOnClickListener ( new View.OnClickListener () {
@Override
public void onClick (View view) {
Intent signUp = new Intent ( MainActivity.this, SignUp.class );
startActivity ( signUp );
}
} );
btnSignIn.setOnClickListener ( new View.OnClickListener () {
@Override
public void onClick (View v) {
Intent signIn = new Intent ( MainActivity.this, SignIn.class );
startActivity ( signIn );
}
} );
}
@Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
My gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "abcd.com.eatme"
minSdkVersion 17
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:27.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation 'com.google.firebase:firebase-core:11.8.0'
implementation 'com.google.android.gms:play-services-auth:11.8.0'
implementation 'com.google.firebase:firebase-core:11.8.0'
implementation 'com.google.firebase:firebase-database:11.8.0'
implementation 'com.github.jd-alexander:android-flat-button:v1.1'
implementation 'com.rengwuxian.materialedittext:library:2.1.4'
implementation 'com.android.support:cardview-v7:27.0.2'
implementation 'com.android.support:recyclerview-v7:27.0.2'
implementation 'com.firebaseui:firebase-ui-database:3.2.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
}
apply plugin: 'com.google.gms.google-services'
My firebase datbase:
androideatit-63d7daddclose
Category
01
Image:
Name:
02
Image:
Name:
03
Image:
Name:
04
Image:
Name:
users
Roger
name: Mac
password: 12345
My Viewholder:
public class MenuViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView textMenuName;
public ImageView imageView;
private ItemClickListener itemClickListener;
public MenuViewHolder (View itemView) {
super ( itemView );
textMenuName = (TextView) itemView.findViewById ( R.id.menu_name );
imageView = (ImageView)itemView.findViewById ( R.id.menu_image);
itemView.setOnClickListener ( this );
}
public void setItemClickListener (ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
@Override
public void onClick (View view) {
itemClickListener.onClick ( view, getAdapterPosition (), false );
}
}
回答1:
I managed to solve it
instead of :
@Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
in MainActivity. Transfer this line adapter.startListening(); inside the loadMenu() before setting the adapter:
adapter.startListening();
recycler_menu.setAdapter(adapter);
回答2:
The error you get is:
Attempt to invoke virtual method 'void com.firebase.ui.database.FirebaseRecyclerAdapter.startListening()' on a null object reference at abcd.com.eatme.MainActivity.onStart(MainActivity.java:55)
If you go to line 55 of MainActivity.java that the error mentions, it is in onStart()
:
@Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
Specifically adapter.startListening();
is listening, because adapter
doesn't have a value yet.
And indeed, the rest of the code you shared never creates a FirebaseRecyclerAdapter
, so you can't start listening on it. I recommend that you check out the documentation for FirebaseUI, which shows how to create a FirebaseRecyclerAdapter
:
FirebaseRecyclerOptions<Chat> options =
new FirebaseRecyclerOptions.Builder<Chat>()
.setQuery(query, Chat.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(options) {
...
来源:https://stackoverflow.com/questions/48847282/startlistening-in-firebase-ui