Утечка памяти FragmentStatePagerAdapter в Android < 7.0
Мы пытаемся создать приложение, в котором мы можем пролистывать между pdf 1 страницы. Существует много PDF, поэтому мы использовали FragmentStatePagerAdapter и https://github.com/barteksc/AndroidPdfViewer. Но у нас есть утечка памяти. После считывания заданного количества PDF-файлов происходит сбой приложения (зависит от используемого телефона, но обычно от 15 до 30 PDF-файлов).
Странно то, что у нас проблема только на версии ниже Android Nougat. (Я тестировал только на 7.1.1, 6.0 и 5.1).
Вот монитор памяти в Android 7.1.1 и 5.1:
Каждая красная стрелка соответствует движению. Как видите, в Android 5.1 память не освобождается.
Вот Активность и Фрагмент, который мы используем, чтобы сделать наш PageViewer:
DiyApproachActivity.java
public class DiyApproachActivity extends AppCompatActivity {
public static HashMap<String, Integer> hashFragment2;
public static List<Fragment> fragments;
ViewPager mPager;
PDFViewPagerAdapter pdfViewPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diy_approach);
ArrayList<String> formulaDisplayed1 = CurrentFormulaManager.getInstance(this).getDiplayedFormulas();
int i1 = formulaDisplayed1.indexOf(CurrentFormulaManager.getInstance(getApplicationContext()).getCurrentIdHighTech());
int j = 0;
while (j < i1) {
formulaDisplayed1.add(formulaDisplayed1.get(0));
formulaDisplayed1.remove(0);
j++;
}
final ArrayList<String> formulaDisplayed = new ArrayList<>();
for (String idHighTech : formulaDisplayed1) {
if (!ChooseFormulaActivity.masque) {
if (!HiddenFormulaManager.getInstance(getApplicationContext()).getHiddenFormulas().contains(idHighTech)) {
formulaDisplayed.add(idHighTech);
}
} else {
formulaDisplayed.add(idHighTech);
}
}
CurrentFormulaManager.getInstance(this).setDiplayedFormulas(formulaDisplayed);
mPager = (ViewPager) findViewById(R.id.pager);
fragments = new ArrayList<>();
hashFragment2 = new HashMap<>();
for (int i = 0; i < formulaDisplayed.size(); i++) {
String idHighTech = formulaDisplayed.get(i);
fragments.add(ContentFragment.newInstance(idHighTech,
DatabaseManager.getInstance(this).isWithExtraText(idHighTech)));
hashFragment2.put(idHighTech, i);
}
pdfViewPagerAdapter = new PDFViewPagerAdapter(getSupportFragmentManager(), fragments);
mPager.setAdapter(pdfViewPagerAdapter);
}
private static class PDFViewPagerAdapter extends FragmentStatePagerAdapter {
List<Fragment> mFrags = new ArrayList<>();
PDFViewPagerAdapter(FragmentManager fm, List<Fragment> frags) {
super(fm);
mFrags = frags;
}
@Override
public Fragment getItem(int position) {
int index = position % mFrags.size();
return mFrags.get(index);
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}
}
ContentFragment.java
public class ContentFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public static int d = 0;
public static int i = 0;
PDFView pdfView;
private String mParam2;
public ContentFragment() {
// Required empty public constructor
}
public static ContentFragment newInstance(String param2, boolean param1) {
ContentFragment fragment = new ContentFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM2, param2);
args.putBoolean(ARG_PARAM1, param1);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_content, container, false);
pdfView = (PDFView) view.findViewById(R.id.pdfTest);
try {
pdfView.fromBytes(DatabaseManager.getInstance(getContext()).getFile(mParam2))
.password(
GenericErrorsCallBacksManager.getInstance().shorten(
GenericErrorsCallBacksManager.getInstance().genericCallBackFor(mParam2)
)
)
.pages(1)
.enableSwipe(false)
.swipeHorizontal(false)
.enableDoubletap(false)
.enableAnnotationRendering(false)
.onRender(new OnRenderListener() {
@Override
public void onInitiallyRendered(int pages, float pageWidth,
float pageHeight) {
pdfView.fitToWidth();// optionally pass page number
}
}).load();
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
e.printStackTrace();
}
return view;
}
}
И связанные XML-файлы:
fragment_content.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container_fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:orientation="horizontal">
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfTest"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.github.barteksc.pdfviewer.PDFView>
</LinearLayout>
activity_diy_approach.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
Как мы можем освободить память после каждого удара даже в более низкой версии Android? А также почему это происходит в версии