2016-01-16 75 views
0

我有一個問題,只出現幾個小時的不活動後,我研究了它的嘗試各種方式來修復它無濟於事。這個問題是在我的應用程序休眠了好幾個小時後,我的碎片引用爲空,但是;他們仍然存在於碎片管理器中。我使用引用來拉標籤,或者通過findfragmentby ...()獲得id,這樣我就可以調用它們中的特定方法來更新自己,而不是更新它們。這些片段是動態的,並有一個用戶界面。我有幾項活動和一項主要活動要求的服務。我可以關閉應用程序並恢復,調用活動,從服務中提取信息,關閉,使用後退按鈕,全部沒有問題。爲了讓您的應用程序是如何構成的一個想法......片段參考null在簡歷

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"); 

     } 
} 

移動到哪裏片段以viewager使用活動...

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中的一個空指針引用上調用一個方法,它實際上是否會崩潰。

回答

0

發生這種情況是因爲您正在搞亂Android框架爲您處理Fragments的方式。當ViewPagerAdapter在getItem(int)中從您那裏獲取碎片時,它使用您給它的FragmentManager來附加碎片。一旦活動因內存不足而死亡,FragmentManager將自動創建碎片的新實例。此時,有兩個片段副本,即FragmentManager創建的副本和您在appClass中重新創建的副本。

你不應該保留對你的片段的引用。 FragmentManager可以自由銷燬它們並創建新的。如果您需要在ViewPager中的Activity和Fragments之間進行通信,則可以使Fragment詢問其活動的命令,使用事件總線,或者探索粗略的解決方案here