我有一个只在几个小时不活动后出现的问题,我研究了它已经尝试了各种方法来修复它无济于事。问题是在我的应用程序休眠几个小时之后,我的片段的引用为空;他们仍然存在于frag经理中。我使用引用来拉取标记,或者通过findfragmentby ...()使用id,这样我就可以在其中调用特定的方法来更新自己,什么不可以。片段是动态的并且具有UI。我有几个活动和主要活动调用的服务。我可以关闭应用程序并恢复,调用活动,从服务中提取信息,关闭,使用后退按钮,所有这些都没有问题。为了让您了解应用程序的结构......
public class appClass extends Application {
public Fragment fragmentA;
public Fragment fragmentB;
public Fragment fragmentC;
@Override
public void onCreate() {
super.onCreate();
new fragmentTemplate();
fragemntA = fragmentTemplate.newInstance(getDbName(), usefuldata, "A List");
new fragmentTemplate();
fragemntB = fragmentTemplate.newInstance(getDbName(), usefuldata, "B list");
new fragmentTemplate();
fragemntC = fragmentTemplate.newInstance(getDbName(), usefuldata, "C list");
}
}
继续进行在视图中使用片段的活动......
public class mainActivity extends AppCompatActivity implements ...listeners{
appClass myAppClass;
FragmentManager FragMgr;
ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myAppClass = (appClass) getApplication();
setTheme(myAppClass.getAppTheme());
setContentView(R.layout.activity_my_layout);
//toolbar actionbar stuff
FragMgr = getSupportFragmentManager();
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new ViewPagerAdapter(FragMgr));
//tab setup
}
//inner class pager adapter is here
}
这是我的寻呼机适配器
class ViewPagerAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener{
Fragment fragment;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
if (myAppClass.fragmentA != null) {
fragment = myAppClass.fragemntA ;
}
break;
case 1:
if (myAppClass.fragmentB != null) {
fragment = myAppClass.fragmentB ;
}
break;
case 2:
if (myAppClass.fragmentC != null) {
fragment = myAppClass.fragmentC ;
}
break;
}
return fragment;
}
@Override
public int getCount() {
return 3;
}
}
我有一个FAB,它的监听器看起来像这样
@Override
public void onClick(View v) {
Fraggment fragment;
int i = viewPager.getCurrentItem();
if (v.getId() == floatingActionButton.getId()) {
switch (i) {
case 0:
fragment= (Fragment) FragMgr.findFragmentByTag(myAppClass.fragmentA.getTag());
fragment.addItem(fragment.getSomeString());
break;
case 1:
fragment= (Fragment) FragMgr.findFragmentByTag(myAppClass.fragmentB.getTag());
fragment.addItem(fragment.getSomeString());
break;
case 2:
fragment= (Fragment) FragMgr.findFragmentByTag(myAppClass.fragmentC.getTag());
fragment.addItem(fragment.getSomeString());
break;
}
}
}
片段代码
public class fragmentTemplate extends Fragment implements RecyclerAdapter.aListener {
private appClass myAppclassReference;
private RecyclerView recyclerView;
private View view;
private FragmentTitle;
public static fragmentTemplate newInstance(String a, String b, String c) {
Bundle args = new Bundle();
args.putString(KEY_A, a);
args.putString(KEY_B, b);
args.putString(KEY_C, c);
fragmentTemplate fragment = new fragmentTemplate();
fragment.setArguments(args);
return fragment;
}
public String getFragmentTitle() {
return fragmentTitle;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) {
view = inflater.inflate(R.layout.list, container, false);
myAppclassReference= ((appClass) getActivity().getApplication());
recyclerView = (RecyclerView) view.findViewById(R.id.listView);
//get list is a local function that loads a list from a db source
RecyclerAdapter recycler = new RecyclerAdapter(getActivity(), getList());
recycler.setListener(this);
recyclerView.setAdapter(recycler);
recyclerView.setLayoutManager(newLearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {}};
return view;
}
}
当事情变得不稳定时,应用程序不会立即崩溃,标签仍然滚动,viewpager仍然滚动,但它是空的,直到我点击FAB我才得到nullpointerexception,试图调用一个方法onClick Listener中的nullpointer引用确实会崩溃。
答案 0 :(得分:0)
这种情况正在发生,因为您正在搞乱Android框架为您处理Fragments的方式。当ViewPagerAdapter在getItem(int)
中从您那里获取片段时,它会使用您为其附加片段的FragmentManager。一旦Activity因内存不足而被杀死,FragmentManager将自动创建Fragments的新实例。此时,有两个片段副本,FragmentManager创建的片段以及您在appClass中重新创建的片段。
您永远不应该保留对碎片的引用。 FragmentManager可以自由地销毁它们并创建新的。如果您需要在ViewPager中的Activity和Fragments之间进行通信,您可以让Fragment询问其Activity的命令,使用Event Bus,或者探索粗略的解决方案here。