尝试调用虚拟方法:错误java.lang.NullPointerException

时间:2020-03-21 20:18:04

标签: java android android-studio firebase-realtime-database android-recyclerview

我的logcat中出现以下错误

2020-03-21 16:58:54.611 20322-20322/com.example.bookitup E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bookitup, PID: 20322
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
    at com.example.bookitup.RecyclerView_Config.setConfig(RecyclerView_Config.java:22)
    at com.example.bookitup.MainActivity$2.DataIsLoaded(MainActivity.java:90)
    at com.example.bookitup.BookDatabaseEdit$1.onDataChange(BookDatabaseEdit.java:40)
    at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.2.1:75)
    at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.2.1:63)
    at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.2.1:55)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

2020-03-21 16:58:54.622 2004-2019 /? W / ActivityTaskManager:强制完成活动com.example.bookitup / .MainActivity 2020-03-21 16:58:54.622 2004-20389 /? I / DropBoxManagerService:添加标签= data_app_crash isTagEnabled = true标志= 0x2

这是导致此NPE的RecyclerView_Config的代码。

public class RecyclerView_Config {
    private Context mContext;
    private BooksAdapter mBooksAdapter;
    public void setConfig(RecyclerView recyclerView, Context context, List<BookActivity> books, List<String> keys){
        mContext = context;
        mBooksAdapter = new BooksAdapter(books,keys);
        recyclerView.setLayoutManager(new LinearLayoutManager(context));/*here!!!!!!!!!!!!!!!!!!!!!!!!!*/
        recyclerView.setAdapter(mBooksAdapter);
    }

    class BookItemView extends RecyclerView.ViewHolder {
        private TextView mTitle;
        private TextView mAuthor;
        private TextView mISBN;
        private TextView mCategory;

        private String key;
        public BookItemView(ViewGroup parent){
            super(LayoutInflater.from(mContext).inflate(R.layout.book_list_item,parent,false));
            mTitle = (TextView) itemView.findViewById(R.id.title_txtView);
            mAuthor = (TextView) itemView.findViewById(R.id.author_txtView);
            mCategory = (TextView) itemView.findViewById(R.id.category_txtView);
            mISBN = (TextView) itemView.findViewById(R.id.isbn_txtView);

        }
        public void bind(BookActivity book, String key){
            mTitle.setText(book.getXbook());
            mAuthor.setText(book.getXauthor());
            mCategory.setText(book.getXdescription());
            mISBN.setText(book.getXisbn());
            this.key = key;
        }
    }

    class BooksAdapter extends RecyclerView.Adapter<BookItemView>{
        private List<BookActivity> mBookList;
        private List<String> mKeys;

        public BooksAdapter(List<BookActivity> mBookList, List<String> mKeys) {
            this.mBookList = mBookList;
            this.mKeys = mKeys;
        }

        @NonNull
        @Override
        public BookItemView onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new BookItemView((parent));
        }

        @Override
        public void onBindViewHolder(@NonNull BookItemView holder, int position) {
            holder.bind(mBookList.get(position), mKeys.get(position));
        }

        @Override
        public int getItemCount() {
            return mBookList.size();
        }
    }
}

这是我活动中的代码

    public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;
    private RecyclerView mRecyclerView;
    //private ProgressBar progressBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.AppTheme_NoActionBar);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();

        if (user != null) {
            //setContentView(R.layout.activity_main);
            Toolbar toolbar = findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
            FloatingActionButton fab = findViewById(R.id.fab);
            Toast.makeText(getApplicationContext(), "on the main page", Toast.LENGTH_LONG).show();
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                   //Snackbar.make(view, "Adding new book, please wait!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
                    Toast.makeText(getApplicationContext(), "Adding new book, please wait ", Toast.LENGTH_LONG).show();
                    //progressBar.setVisibility(View.GONE);
                    Intent intent = new Intent(MainActivity.this, AddBookActivity.class);
                    startActivity(intent);
                }
            });
            DrawerLayout drawer = findViewById(R.id.drawer_layout);
            NavigationView navigationView = findViewById(R.id.nav_view);




            // Passing each menu ID as a set of Ids because each
            // menu should be considered as top level destinations.
            mAppBarConfiguration = new AppBarConfiguration.Builder(
                    R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
                    R.id.nav_tools, R.id.nav_share, R.id.nav_send, R.id.nav_profile_edit)
                    .setDrawerLayout(drawer)
                    .build();
            NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
            NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
            NavigationUI.setupWithNavController(navigationView, navController);


            //piling all books on the main page
            mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview_books);
            new BookDatabaseEdit().readBooks(new BookDatabaseEdit.DataStatus() {
                @Override
                public void DataIsLoaded(List<BookActivity> books, List<String> keys) {
                    new RecyclerView_Config().setConfig(mRecyclerView,MainActivity.this,books,keys);
                }

                @Override
                public void DataIsInserted() {

                }

                @Override
                public void DataIsUpdated() {

                }

                @Override
                public void DataIsDeleted() {

                }
            });
        }
        else {
            Intent intent = new Intent(MainActivity.this, RegistrationActivity.class);
            startActivity(intent);
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_settings:
                // User chose the "Settings" item, show the app settings UI...
                return true;

            case R.id.action_logout:
                FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                FirebaseAuth.getInstance().signOut();
                Intent intent = new Intent(MainActivity.this, LoginActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                startActivity(new Intent(intent));
                return true;

            default:
                // If we got here, the user's action was not recognized.
                // Invoke the superclass to handle it.
                return super.onOptionsItemSelected(item);

        }
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }
}

我的BookDatabaseEdit.java

public class BookDatabaseEdit {
    private FirebaseDatabase mDatabase;
    private DatabaseReference mReferenceBooks;
    private List<BookActivity> books = new ArrayList<>();

    public interface DataStatus{
        void DataIsLoaded(List<BookActivity> books, List<String> keys);
        void DataIsInserted();
        void DataIsUpdated();
        void DataIsDeleted();
    }
    public BookDatabaseEdit() {
        mDatabase = FirebaseDatabase.getInstance();
        mReferenceBooks = mDatabase.getReference("Booklist");
    }
    public void readBooks(final DataStatus dataStatus){
        mReferenceBooks.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange( DataSnapshot dataSnapshot) {
                books.clear();
                List<String> keys = new ArrayList<>();
                for(DataSnapshot keyNode : dataSnapshot.getChildren()){
                    keys.add(keyNode.getKey());
                    BookActivity book = keyNode.getValue(BookActivity.class);
                    books.add(book);
                }
                dataStatus.DataIsLoaded(books,keys);
                System.out.println(keys);
                System.out.println(books);
            }


            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
}

2 个答案:

答案 0 :(得分:0)

我认为您应该为Context实现一个getter和setter,并使用getter通过null检查获取上下文。

答案 1 :(得分:0)

因此,我已修复此错误,并且我的代码现在可以正常工作。问题出在RecyclerView_Config.java上。问题是,基本上,我的程序试图在创建应用之前将Firebase中的数据填充到应用中。

它是固定的,谢谢大家。

相关问题