如图:
在这里插入图片描述在这里插入图片描述

全局搜索首页是信息流的形式显示展示,搜索页就是 Viewpager+Tablayout+Fragment,下面说下内存优化。
1.Viewpager+Tablayout+Fragment的优化,针对这个我还专门写了个例子去测试,结果从leakcanary发现切换fragment的时候泄露很严重,这是demo里我之前的写法,

1.MainActivity.java:
 package coolpad.testlistfragment;

import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private TabLayout mTbClassify;
    private ViewPager mVp;
    List<Fragment> mFragmentList = new ArrayList<>();
    List<String> mTitles = new ArrayList<>();
    private TablayoutAdapter tabLayoutAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initId();
        initFragments();
        initTitles();
        initView();
    }

    private void initTitles() {
        if (mTitles.size() >0 ){
            mTitles.clear();
        }
        mTitles.add("1");
        mTitles.add("2");
        mTitles.add("3");
        mTitles.add("4");
        mTitles.add("5");
    }

    private void initView() {
        mTbClassify.addTab(this.mTbClassify.newTab().setText("1"), false);
        mTbClassify.addTab(this.mTbClassify.newTab().setText("2"), true);
        mTbClassify.addTab(this.mTbClassify.newTab().setText("3"), false);
        mTbClassify.addTab(this.mTbClassify.newTab().setText("4"), false);
        mTbClassify.addTab(this.mTbClassify.newTab().setText("5"), false);
        tabLayoutAdapter = new TablayoutAdapter(getSupportFragmentManager());
        tabLayoutAdapter.setFragments(mFragmentList);
        tabLayoutAdapter.setTitles(mTitles);
        mVp.setAdapter(tabLayoutAdapter);
        mVp.setCurrentItem(1);
        mVp.setOffscreenPageLimit(1);
        mTbClassify.setupWithViewPager(mVp);
        mTbClassify.setTabsFromPagerAdapter(tabLayoutAdapter);
    }

    private void initFragments() {
        FragmentOne fragmentOne = new FragmentOne();
        FragmentTwo fragmentTwo = new FragmentTwo();
        FragmentThree fragmentThree = new FragmentThree();
        FragmentFour fragmentFour = new FragmentFour();
        FragmentFive fragmentFive = new FragmentFive();
        if (mFragmentList.size() >0){
            mFragmentList.clear();
        }
        mFragmentList.add(fragmentOne);
        mFragmentList.add(fragmentTwo);
        mFragmentList.add(fragmentThree);
        mFragmentList.add(fragmentFour);
        mFragmentList.add(fragmentFive);
    }

    private void initId() {
        mTbClassify = findViewById(R.id.my_tab);
        mVp = findViewById(R.id.vp_pager);
    }
}

2.TablayoutAdapter.java:
package coolpad.testlistfragment;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class TablayoutAdapter extends FragmentStatePagerAdapter {
    List<String> mTitleList = new ArrayList<>();
    List<Fragment> mFragmentList = new ArrayList<>();
    TabLayout tabLayout;

    public TablayoutAdapter(FragmentManager fm) {
        super(fm);
    }

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

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

    public void setFragments(List<Fragment> fragmentList){
        mFragmentList = fragmentList;
    }


    public void setTitles(List<String> stringList){
        mTitleList = stringList;
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return mTitleList.get(position);
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        super.destroyItem(container, position, object);
    }
}

这样的结果是当加载后去切换各个页面,直接内存泄露,比如日志如下:

coolpad.testlistfragment.FragmentOne instance
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     Leaking: YES (ObjectWatcher was watching this because coolpad.testlistfragment.FragmentOne received
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     Retaining 1.2 kB in 36 objects
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     key = df391035-e3e5-4b5d-85da-53050bfe9930
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     watchDurationMillis = 5364
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     retainedDurationMillis = 363
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     key = 075f36bb-0e68-4e22-b2f9-a26dcd5214ac
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     watchDurationMillis = 6920
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     retainedDurationMillis = 1920
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     key = f9464c48-9f3e-4969-a222-fbb1484a7d6f
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     watchDurationMillis = 7355
2021-03-30 17:31:08.523 12950-13056/coolpad.testlistfragment D/LeakCanary: ​     retainedDurationMillis = 2355

这是什么问题?由于你的fragmentlist一直持有fragment实例对象,导致无法释放掉fragment造成内存泄漏,具体可以参考[https://blog.csdn.net/K_Hello/article/details/82996162],然后又两个修改方法,方法一:
修改viewpager默认加载的条目为5,那我在加载五个Tab的时候就会一次性加载所有,切换的时候也不会销毁,也就不会泄露了,但是这种操作会导致fragment里的webview加载很慢,因为一次性加载五个webview,影响用户体验。
方法二:
修改TabAdapter的对fragment的加载方式

package coolpad.testlistfragment;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class TablayoutAdapter extends FragmentStatePagerAdapter {
    List<String> mTitleList = new ArrayList<>();
//    List<Fragment> mFragmentList = new ArrayList<>();

    public TablayoutAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        if (position == 0){
            return new FragmentOne();
        }else if (position == 1){
            return new FragmentTwo();
        }else if (position == 2){
            return new FragmentThree();
        }else if (position == 3){
            return new FragmentFour();
        }else if (position == 4){
            return new FragmentFive();
        }
    }

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

//    public void setFragments(List<Fragment> fragmentList){
//        mFragmentList = fragmentList;
//    }


    public void setTitles(List<String> stringList){
        mTitleList = stringList;
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return mTitleList.get(position);
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        super.destroyItem(container, position, object);
    }
}

getItem的时候直接new出来,这种修改也不会内存泄漏。
2.Webview的优化
见我之前写的添加链接描述

在执行完这两种操作后就不会内存泄露了。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐