getContext() 在调用 update RecyclerView 函数时使我的应用程序崩溃?

getContext() crashes my App when calling update RecyclerView function?

提问人:EXTSY 提问时间:11/12/2022 最后编辑:EXTSY 更新时间:11/13/2022 访问量:58

问:

当我想访问特定片段时,我的应用程序总是崩溃。错误是:

致命异常:main 进程:com.akstudios.kindergarten,PID:15680 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)” 在com.akstudios.kindergarten.GroupbookKrippeFragment.setRecyclerView(GroupbookKrippeFragment.java:56)

我过去看到很多人都有类似的问题,但没有想法或建议帮助我解决我的问题。

我尝试使用 getContext()、onAttach()、GroupbookKrippeFragment.this.getContext() 和其他一些方式获取上下文。

更新开始 (12.11.22)

我能够进一步缩小问题范围。 该应用程序稳定且有效,直到我进行了以下更改:

1.)为了使用来自我的数据库的 recyclerview 条目更新我的 tableList,我将以下代码封装到 GroupbookKrippeFragment.java 中的新方法中:

public void setRecyclerView(List<ChildrenTable> childrenTableList) {
        recycler_view.setLayoutManager(new LinearLayoutManager(getContext()));
        childAdapter = new ChildAdapter(getContext(), childrenTableList);
//        childAdapter = new ChildAdapter(getContext());
        recycler_view.setAdapter(childAdapter);
    }

2.) 我在 AllChildren 的 onPostExecute() AsyncTask 的 DatabaseHelper.java 类中调用了此方法:

public class DatabaseHelper {
Context context;
GroupbookKrippeFragment groupbookKrippeFragment = new GroupbookKrippeFragment();

public DatabaseHelper(Context context) {
    this.context = context;
}

public static DatabaseHelper getInstance(Context context) {
    return new DatabaseHelper(context);
}

// Insert Data
// TODO: Add all columns as Input parameter for Database
public void addNewChild(
        String child_name, String child_surname, String child_birthday,
        String child_birthday_location, String child_confession, String child_nationality) {

    class NewChild extends AsyncTask<Void, Void, ChildrenTable> {

        @Override
        protected ChildrenTable doInBackground(Void... voids) {
            ChildrenTable childrenTable = new ChildrenTable();

            // TODO: Link all columns for Database
            childrenTable.setChild_name(child_name);
            childrenTable.setChild_surname(child_surname);
            childrenTable.setChild_birthday(child_birthday);
            childrenTable.setChild_birthday_location(child_birthday_location);
            childrenTable.setChild_confession(child_confession);
            childrenTable.setChild_nationality(child_nationality);

            DatabaseClient.getInstance(context)
                    .getChildrenDatabase()
                    .childrenDAO()
                    .insertData(childrenTable);
            return childrenTable;
        }

        @Override
        protected void onPostExecute(ChildrenTable childrenTable) {
            super.onPostExecute(childrenTable);
            if (childrenTable != null) {
                Toast.makeText(
                        context,
                        childrenTable.getChild_name() + "\n" +
                        childrenTable.getChild_surname(), Toast.LENGTH_SHORT).show();
            }
        }
    }

    NewChild newChild = new NewChild();
    newChild.execute();
}

// Show all data from ChildrenTable
public void getAllChildrenData() {
    class AllChildren extends AsyncTask<Void, Void, List<ChildrenTable>> {

        @Override
        protected List<ChildrenTable> doInBackground(Void... voids) {
            List<ChildrenTable> list = DatabaseClient.getInstance(context)
                    .getChildrenDatabase()
                    .childrenDAO()
                    .selectAll();
            return list;
        }

        @Override
        protected void onPostExecute(List<ChildrenTable> childrenTable) {
            super.onPostExecute(childrenTable);
            if (childrenTable != null && childrenTable.size() > 0) {
                groupbookKrippeFragment.setRecyclerView(childrenTable);
            }

        }
    }

    AllChildren allChildren = new AllChildren();
    allChildren.execute();
}

}

每当我注释掉这个方法调用并将该方法中的行移动到 GroupbookKrippeFragment 的 onViewCreated 中时,该应用程序再次稳定,但 recyclerView 数据没有显示并更新我的数据库。

更新结束 (12.11.22)

非常感谢您的帮助 - 这是我的文件:

GroupbookKrippeFragment.java

public class GroupbookKrippeFragment extends Fragment {

Button addChildBtn;
RecyclerView recycler_view;
ChildAdapter childAdapter;
DatabaseHelper helper;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_groupbook_krippe, container, false);

    addChildBtn = view.findViewById(R.id.btn_groupBook_krippe_1);
    addChildBtn.setOnClickListener(view1 -> {
        Intent intent = new Intent(GroupbookKrippeFragment.this.getActivity(), GroupbookAddChildFragment.class);
        startActivity(intent);
    });

    recycler_view = view.findViewById(R.id.recycler_view);

    helper = DatabaseHelper.getInstance(getContext());
    helper.getAllChildrenData();

    return view;
}

public void setRecyclerView(List<ChildrenTable> childrenTableList) {
    recycler_view.setLayoutManager(new LinearLayoutManager(getContext()));
    childAdapter = new ChildAdapter(getContext(), childrenTableList);
    recycler_view.setAdapter(childAdapter);
  }
}

GroupbookFragment.java

public class GroupbookFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_groupbook, container, false);

    // Tab layout initialization
    TabLayout tabLayout = view.findViewById(R.id.tabLayout);
    ViewPager2 viewPager = view.findViewById(R.id.viewPager_groupBook);
    GroupbookAdapter adapterGroupBook = new GroupbookAdapter(getChildFragmentManager(), getLifecycle());
    viewPager.setAdapter(adapterGroupBook);

    // set 3 Tab titles
    tabLayout.addTab(tabLayout.newTab().setText("Krippe"));
    tabLayout.addTab(tabLayout.newTab().setText("Hafen"));
    tabLayout.addTab(tabLayout.newTab().setText("Kindergarten"));

    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

    viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {
            tabLayout.selectTab(tabLayout.getTabAt(position));
        }
    });
    return view;
  }
}
android-fragments android-recyclerview nullpointerexception android-context

评论

0赞 Lawrence Gimenez 11/12/2022
你能指出哪一行是 NullPointerException 吗?
0赞 EXTSY 11/12/2022
这是GroupbookKrippeFragment.java中的这一行recycler_view.setLayoutManager(new LinearLayoutManager(getContext()));
0赞 primo 11/12/2022
将代码转换为 onViewCreated() 方法。在 onCreateView() 中仅保留布局膨胀
0赞 EXTSY 11/12/2022
@primo可悲的是,这并没有改变任何事情,也没有解决问题。同样的错误
0赞 Lawrence Gimenez 11/13/2022
不要使用 getContext(),而是使用 getActivity() 或类似方法。

答:

0赞 laalto 11/13/2022 #1

您拥有 .您拥有另一个实例,该实例不涉及片段事务,因此其生命周期方法(例如未调用)在该实例中保持为 null。GroupbookKrippeFragmentDatabaseHelperDatabaseHelperGroupbookKrippeFragmentonCreateView()recycler_view

例如,您可以传入对所属片段的引用作为构造函数参数,将其存储在字段中,并在以后调用它,而不是实例化 。DatabaseHelpernew GroupbookKrippeFragmentsetRecyclerView()

它不是一个完美的设计,但可以帮助您在开发过程中向前迈进一步。