2

Im using fragments to change the ui if a user is navigating through the menu. My problem is, that every time a fragment is replaced by another, the app freezes for a sec because it is processing on the main thread. I have read about using Threads to process things in the background but if a fragment is replaced by another you cant do it, because it has to be loaded in the main thread.

So, is there a way to load fragments in the background to prevent lags if the user navigates through the menu?

Hope you guys understand me, I tried my best. Geigerkind

Edit: For anyone stumbelling about the same problem: Mo Adel's suggustion and this Link helped me solving the problem Optimizing drawer and activity launching speed

Community
  • 1
  • 1

2 Answers2

0

if you changine it from a slide menu or a tab you can do it using this method in your activity

public void switchContent(final Fragment fragment) {
    mContent = fragment;
    getSupportFragmentManager()
    .beginTransaction()
    .replace(R.id.content_frame, fragment)
    .commit();
    Handler h = new Handler();
    h.postDelayed(new Runnable() {
        public void run() {
            sm.showContent();
        }
    }, 50);
}

and add this to the menu_fragment or other fragment that uses to change fragement from

mine is a ListFragment so that what i do

@Override
public void onListItemClick(ListView lv, View v, int pos, long id) {
     ma.setSelecteIndex(pos , v);
     ((Menu_Adapter)lv.getAdapter()).notifyDataSetChanged();
     Fragment newContent;
     if(pos==0){
        newContent = new HomeFragment();
     }else if(pos==1){
        newContent = StoresFragment.NewInstance(pos);
     }else{
        newContent = DinningFragment.NewInstance(pos);
     }
    if (newContent != null)
        switchFragment(newContent);
}

// the meat of switching the above fragment
private void switchFragment(Fragment fragment) {
    if (getActivity() == null)
        return;

    if (getActivity() instanceof CustomAnimation) {
        CustomAnimation ra = (CustomAnimation) getActivity();
        ra.switchContent(fragment);
    }
}
Mo Adel
  • 1,136
  • 1
  • 16
  • 29
  • im using a drawer menu. Can you explain a in a bit more detail how this function prevents lag by loading it this way? Thanks for your help! – user3752974 Jul 02 '14 at 20:00
  • bascially all work will be done in the 50 gab before showing it on the screen. so any animation from closing drawer menu or clicking on an item in the drawer won't lag. and it will do the oncreate method before attaching it to the screen after the 50 ms gab. – Mo Adel Jul 02 '14 at 22:22
  • Ah, okay, can you at Last Show what showContent() does or are you changing there just the content of your loaded fragment? You are a big help! – user3752974 Jul 03 '14 at 05:11
  • In my case show content just closes the SlideMenu and start initialising the views in the new fragment... Please mark the answer with the green tick and upvote if you found it helpful, so it can be useful for others. – Mo Adel Jul 03 '14 at 05:20
0

Make sure the fragment lifecycle code for onCreate()/onCreateView(), (or even onDestroy()/onPause()/onResume()) does not have any heavy work being done on it. You can always use the ADT method profiling tool to see what is slowing down the UI thread during the fragment replacements.

Clarkarot
  • 116
  • 1
  • 9
  • You may exclude **onResume** from the list, as the activity/fragment will already be visible or foreground at that point. – waqaslam Jul 02 '14 at 20:50
  • @waqaslam however, the fragment onResume() is still called at least once, after the onCreate() call. – Clarkarot Jul 02 '14 at 22:46
  • onResume is always called whenever the fragment comes foreground but thats a different debate. What I meant is, the moment onResume hits your fragment will be in visible state. – waqaslam Jul 03 '14 at 00:27
  • onResume() will be called before the fragment is active: http://developer.android.com/guide/components/fragments.html My concern is to move non-UI essential work off of the UI thread, so in an overall sense, the UI thread's perceived performance can be improved, but since onResume() is guaranteed to be called by Android on the UI thread, it should not have any heavy work inside it. – Clarkarot Jul 03 '14 at 00:38
  • 1
    This is wrong **"onResume() will be called before the fragment is active"**. Its the onResume that confirms that the fragment is in active/visible/foreground state - so it is not called before, in fact it itself confirms that the fragment is now visible. Simply call `Thread.sleep` in your fragment's onResume and you'll get the idea what I'm pointing towards. Other than that, I agree we should never put heavy workloads in any of the fragment's override method, unless we spawn it to another thread. – waqaslam Jul 03 '14 at 07:28
  • So then Google's fragment lifecycle diagram here is incorrect then? http://developer.android.com/images/fragment_lifecycle.png I also see that onStart() is the method called to confirm the fragment is visible: http://developer.android.com/reference/android/app/Fragment.html#onStart() – Clarkarot Jul 03 '14 at 19:20