Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make viewpager transition fast with fragment?

Here i have an questions like how to make view pager fast with fragment.

Explanation of what i am doing:

I have a fragment which contains five web view and one list view to show the respective data.Based on the content count i am loading fragment to viewpager with respective data. Implementation wise all good but performance of view pager is very very slow.

Code Snippet:

Pager Adapter loading:

FragmentPagerAdapter mFragmentPagerAdapter = new ViewPagerAdapter(getActivity(), getChildFragmentManager(), takeExamResponse.getPayloads().getQuestions(), mFragmentNavigator, takeExamResponse.getPayloads().getType(), "finished".equals(getArguments().getString("IS_FINISHED")) ? true : false, mQuestionsFragment);
viewPager.setAdapter(mFragmentPagerAdapter);

PagerAdapter:

import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import com.comquest.fragment.ViewPagerFragment;
import com.comquest.interfaces.FragmentNavigator;
import com.comquest.response.Question;
import com.comquest.utilities.EGApplication;

import java.util.List;


public class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Question> takeExamResponse;
    private final Context context;
    FragmentNavigator fragmentNavigator;
    String type = "";
    private boolean isFinshed;
    private EGApplication.Listener mListener;

    public ViewPagerAdapter(Context context, FragmentManager fm, List<Question> response, FragmentNavigator fragmentNavigator, String type, boolean isFinshed, EGApplication.Listener mListener) {
        super(fm);
        this.takeExamResponse = response;
        this.isFinshed = isFinshed;
        this.context = context;
        this.mListener = mListener;
        this.fragmentNavigator = fragmentNavigator;
        this.type = type;
    }

    @Override
    public Fragment getItem(int position) {
        return ViewPagerFragment.newInstance(context, takeExamResponse.get(position), fragmentNavigator, type, isFinshed, mListener, position);
    }

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

    @Override
    public int getItemPosition(Object object) {
        notifyDataSetChanged();
        return POSITION_NONE;
    }

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    super.destroyItem(container, position, object);
}
}

I am doing exam kind of app, which has 100 to 150 question for each exam. When i am loading 30 to 150 question by using fragments app getting slow and crashed sometimes.

There is uncaught exception message

07-31 23:50:25.350 22065-22065/exam.test E/ApkAssets: Error while loading asset assets/natives_blob_64.bin: java.io.FileNotFoundException: assets/natives_blob_64.bin
07-31 23:50:25.350 22065-22065/exam.test E/ApkAssets: Error while loading asset assets/snapshot_blob_64.bin: java.io.FileNotFoundException: assets/snapshot_blob_64.bin
07-31 23:50:27.499 22065-23275/exam.test E/libEGL: validate_display:255 error 3008 (EGL_BAD_DISPLAY)
07-31 23:52:00.941 22065-22065/exam.test E/libc++abi: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
07-31 23:52:01.359 22065-22065/exam.test A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 22065

I need some optimal solution for this.

like image 391
learner Avatar asked Mar 11 '23 14:03

learner


2 Answers

UPDATE:

To detect the problem, I recoomend you to try :

  1. Check AndroidStudio's Memory Monitor to confirm there is no problems with memory.

  2. Hide the part of layout in Fragment. Then if the swipe becomes smooth, the problem is in layout.

  3. Try Hardware Acceleration. It might improve.

ORIGINAL

std::bad_alloc might be caused by memory leak.

FragmentPagerAdapter keeps fragments in memory. (When fragment becames invisible, fragment is only detachted, not removed.) After you swiped many pages, there would be insufficient memory.

So you should use FragmentStatePagerAdapter.
FragmentStatePagerAdapter remove fragments when fragment becomes invisible.

Or you should delete a reference from Fragment in onDestoryView method. like this:

public class ViewPagerFragment extends Fragment {

    ...
    private FragmentNavigator fragmentNavigator;
    private String type = "";
    private boolean isFinshed;
    private Question question;
    private EGApplication.Listener mListener;
    ...

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        fragmentNavigator = null;
        mListener = null;
        question = null;
        //other things might be necessary for prevent memory leaks.
    }
}
like image 103
nshmura Avatar answered Apr 30 '23 15:04

nshmura


viewpager.setOffscreenPageLimit(count); 

for the offscreen amount of pages, or use a FragmentStatePagerAdapter. also asynctask can lead to memory leaks make sure that you use them correctly in your fragments.

like image 23
locomain Avatar answered Apr 30 '23 15:04

locomain