视图寻呼机中的片段在活动重启时生成致命错误

时间:2016-03-20 16:13:17

标签: android android-viewpager

我有一个活动,显示存储在数据库中的数据,这些数据存储在以片段形式组织的视图寻呼机中。

当适配器初始化View Pager时,它调用每个片段中的一个方法,将数据库条目的id传递给retrive并显示:

        public Fragment getItem(int position) {
        switch (position) {
            case 0: // Fragment # 0 - This will show FirstFragment different title
                firstFragment = Fragment.newInstance(1, "Page # 1");
                firstFragment.setID(ctx, id);
                return firstFragment;
            case 1: // Fragment # 0 - This will show FirstFragment different title
                secondFragment = Fragment.newInstance(1, "Page # 2");
                secondFragment.setID(ctx, id);
                return secondFragment;
            case 2: // Fragment # 0 - This will show FirstFragment
                thirdtFragment = Fragment.newInstance(1, "Page # 3");
                thirdtFragment.setID(context, id);
                return thirdtFragment;

            default:
                return null;
        }
    }

当调用片段的onCreateView方法时,它会从数据库中检索数据并初始化向用户显示数据的所有视图:

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


    DataManager dataManager = new DataManager(mContext);
    DataModel data = dataManager.getData(mID);
    .....

所有似乎都工作正常,除非用户重新启动应用程序时,例如在此活动内部暂停:当活动重新启动时,我得到一个致命的错误访问数据,就好像包含片段的私有变量一样从垃圾收集器中删除数据的ID。

我的方法是否正确?如何防止活动重新启动时产生的错误?

2 个答案:

答案 0 :(得分:1)

onPause期间onResume片段和活动由android管理,因此您可能无法检索成员变量,以便在Fragment的newInstance方法中克服此问题像

public static Fragment newInstance(int id, String page){
    Bundle bundle = new Bundle();
    bundle.putString("page", page);
    bundle.putInt("ID", page);
    setArguments(bundle);
}

并在onCreateView回调中使用类似

的内容
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    int mID = getArguments().getInt("ID");
    DataManager dataManager = new DataManager(mContext);
    DataModel data = dataManager.getData(mID);
    ...

答案 1 :(得分:0)

所以,我通过以下方式解决了我的问题:

  • 创建一个包含片段列表及其各自标题的视图寻呼机。此视图寻呼机适配器应具有将片段添加到列表的方法。这是我的代码:

    public class ViewPagerAdapter extends FragmentPagerAdapter {
       private final List<Fragment> mFragmentList = new ArrayList<>();
       private final List<String> mFragmentTitleList = new ArrayList<>();
       private int mItemId;
    
       public ViewPagerAdapter(FragmentManager manager, int id) {
          super(manager);
          mItemId = id;
       }
    
       @Override
       public Fragment getItem(int position) {
          return mFragmentList.get(position);
       }
    
       @Override
       public int getCount() {
          return mFragmentList.size();
       }
    
       public void addFrag(Fragment fragment, String title) {
          Bundle bundle = new Bundle();
          bundle.putInt("itemId", mItemId);
          fragment.setArguments(bundle);
          mFragmentList.add(fragment);
          mFragmentTitleList.add(title);
       }
    
       @Override
       public CharSequence getPageTitle(int position) {
          return mFragmentTitleList.get(position);
       }}
    
  • 现在,在Fragment中,你可以提取额外的包,它可以帮助你从数据库中读取一些数据,例如,如果它是表列的id。这可能是你的片段类:

    public class InfoFragment extends Fragment {
    
        private Activity mActivity;
    
        private CustomerDbObject customer;
        private int customerId;
    
        public InfoFragment() {
          // Required empty public constructor
        }
    
        @Override
        public void onAttach(Context ctx){
           super.onAttach(ctx);
    
           if (ctx instanceof Activity){
              this.mActivity = (Activity) ctx;
           }
    
           customerId = getArguments().getInt("itemId");
    
           Realm realm = Realm.getInstance(ctx);
    
           RealmQuery<Customer> query = realm.where(Customer.class);
    
           query = query.equalTo("account_id", customerId);
    
           customer = query.findFirst();
       }
    
       @Override
       public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
          View view = inflater.inflate(R.layout.customer_fragment_info, container, false);
    
          ButterKnife.bind(this, view);
    
          return view;
      }}
    
  • 有了这两个部分,我们现在需要的是我们的活动,它将显示带有标签的viewpager!请记住,在同一个活动中,我们向viewpager实例提供额外的(itemId),然后viewpager将按顺序将其传递给片段。

     public class CustomerActivity extends AppCompatActivity {
    
         private int mSelectedCustomer = 5; //this value could be extracted for an intent that is passed from a Recyclerviewer etc
    
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_customer_details);
             Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
             setSupportActionBar(toolbar);
    
             getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    
             final ViewPager mViewPager = (ViewPager) findViewById(R.id.viewPager);
             setupViewPager(mViewPager);
    
             TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
             tabLayout.setupWithViewPager(mViewPager);
    
    
             tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
             @Override
             public void onTabSelected(TabLayout.Tab tab) {
    
                 mViewPager.setCurrentItem(tab.getPosition());
             }
    
             @Override
             public void onTabUnselected(TabLayout.Tab tab) {
    
             }
    
             @Override
             public void onTabReselected(TabLayout.Tab tab) {
    
             }
        });
    
        }
    
        private void setupViewPager(ViewPager viewPager) {
           ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), mSelectedCustomer);
           adapter.addFrag(new InfoFragment(), getString(R.string.info_tab));
        }
    
    }
    

现在我们将所有部分组合在一起,传递的重要额外(数据)应始终通过viewpager适配器提供给Fragment,后者从活动中获取它。

当我测试它时,它起作用了,我希望它对你也有效。请让我知道它是怎么回事!!