2015-06-21 3 views
2

У меня есть 4 фрагмента в приложении для Android. У меня есть FragmentPagerAdapter, чтобы заполнить ViewPager.Fragment Memory Leak

Также я расширяю FragmentActivity в основном действии.

Проблема есть, когда я скольжу по фрагментам, другие фрагменты уничтожаются (сборщиком мусора?). Как я могу избежать этого?

FragmentAdapter:

package com.quiz.Adapter; 

public class FragmentAdapter extends FragmentPagerAdapter { 

    private List<Fragment> fragments = new ArrayList<>(); 
    private Context ctx; 

    public FragmentAdapter(FragmentManager fm, Context ctx) { 
     super(fm); 
     this.ctx = ctx; 
     fragments.add(new FragmentMenu()); //same 
     fragments.add(new FragmentMain()); 
     fragments.add(new FragmentMenu()); //same 
     fragments.add(new FragmentMenu()); //same 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return fragments.get(position); 
    } 

    @Override 
    public int getCount() { 
     return fragments.size(); 
    } 


} 

3 Фрагменты имеют TextView. Другой фрагмент имеет кнопку и индикатор:

package com.quiz.Activity.Fragments; 


public class FragmentMain extends Fragment implements View.OnClickListener { 

    Timer timer; 
    int gameStartIn = 0, ONE = 1, INTERVAL = 1000; 
    Context context; 
    boolean joinedToMulti = false; 
    NormalButton multiGameButton; 
    NextGameCounter nextGameCounter; //progressbar 
    Store store; 


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

     View view = inflater.inflate(R.layout.fragment_main, container, false); 

     context = this.getActivity().getApplicationContext(); 
     store = new Store(context); 
     multiGameButton = (NormalButton)view.findViewById(R.id.multiGameButton); 
     multiGameButton.setOnClickListener(this); 
     nextGameCounter = (NextGameCounter)view.findViewById(R.id.nextGameCounter); 

     init(); 

     Toast("onCreateView"); 


     return view; 
    } 

    void Toast(String e){ 
     Toast.makeText(context, "_"+e, Toast.LENGTH_SHORT).show(); 
    } 

    private void init() { 

     getNextRoundDate(); 

     timer = new Timer(); 
     timer.scheduleAtFixedRate(new TimerTask() { 

      @Override 
      public void run() { 

       gameStartIn--; 

       if(gameStartIn < ONE) { 
        gameStartIn = 1; 
        timer = new Timer(); 
        getNextRoundDate(); 
       } else { 
        //update ui 
        getActivity().runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          nextGameCounter.setProgress(gameStartIn); 
         } 
        }); 
       } 

      } 
     }, 0, INTERVAL); 
    } 

    private void getNextRoundDate() { 
     new AsyncTask<Void, Void, ResponseModel>() { 
      @Override 
      protected ResponseModel doInBackground(Void... voids) { 
       ResponseModel responseModel = ApiManager.getService().GameGetNextRoundDate(); 
       return responseModel; 
      } 

      @Override 
      protected void onPostExecute(ResponseModel e){ 
       gameStartIn = Integer.valueOf(e.getInfo()); //seconds 
      } 
     }.execute(); 
    } 

    @Override 
    public void onClick(View view) { 

     if(view.getId() == R.id.multiGameButton){ 
      if(joinedToMulti) 
       return; 

      joinedToMulti = true; 
      requestNewGame(); 
     } 
    } 

    @Override 
    public void onPause(){ 
     super.onPause(); 
     stopGame(); 
    } 

    @Override 
    public void onResume(){ 
     super.onResume(); 
     multiGameButton.setText(getResources().getString(R.string.main_multiplayer_button_text)); 
    } 

    private void stopGame() { 
     if(joinedToMulti) 
      sendLeaveLobbyRequest(); 
    } 

    void sendLeaveLobbyRequest(){ 
     new AsyncTask<Void, Void, Void>() { 
      @Override 
      protected Void doInBackground(Void... voids) { 
       ApiManager.getService().GameMatchLeaveRequest(new GameMultiRequestModel(store.getUid())); 
       return null; 
      } 
     }.execute(); 
    } 

    void requestNewGame(){ 
     new AsyncTask<Void, Void, ResponseModel>() { 

      @Override 
      protected ResponseModel doInBackground(Void... voids) { 

       return ApiManager.getService().GameMatchRequest(new GameMultiRequestModel(store.getUid())); 
      } 

      @Override 
      protected void onPostExecute(ResponseModel matchResponseModel){ 
       multiGameButton.setText(getString(R.string.main_multiplayer_joined_button_text)); 
       Toast.makeText(context, "Game starting in "+gameStartIn+" seconds.", Toast.LENGTH_LONG).show(); 
      } 

     }.execute(); 
    } 

} 

ответ

2

Вы можете использовать setOffscreenPageLimit (int limit) метод ViewPager увеличить количество фрагментов, хранящихся в памяти.

По умолчанию 1 означает, что в памяти 3 фрагмента. (1 слева и 1 справа от активной).

Вы можете попробовать 2 или 3. Но не стоит слишком высоко, чтобы он мог съесть слишком много памяти.

+1

Я установил предел в 2, и теперь он работает без проблем. Спасибо за ответ. – Lazy