SearchView在Android应用中泄漏内存

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SearchView在Android应用中泄漏内存相关的知识,希望对你有一定的参考价值。

我正在使用泄漏金丝雀来检测我正在开发的应用程序中的内存泄漏,并且它一直表示我的SearchView泄漏内存,有时在搜索中,有时在listview中我加载检索到的数据。

我试图寻找解决方案,但我找不到任何有用的东西。到底是怎么回事?

这是我的搜索框的实现:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_search_team, menu);

        SearchManager searchManager = (SearchManager)
                getSystemService(Context.SEARCH_SERVICE);
        searchMenuItem = menu.findItem(R.id.search);
        searchView = (SearchView) searchMenuItem.getActionView();

        for (TextView textView : findChildrenByClass(searchView, TextView.class)) {
            textView.setTextColor(Color.BLACK);
            textView.setHintTextColor(Color.BLACK);
        }

        searchView.setSearchableInfo(searchManager.
                getSearchableInfo(getComponentName()));
        searchView.setSubmitButtonEnabled(true);
        searchView.setOnQueryTextListener(this);

        return true;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {

        searchMenuItem.collapseActionView();
        searchView.onActionViewCollapsed();
        viewPager.bringToFront();
        listview.setVisibility(View.GONE);
        appBarLayout.setVisibility(View.VISIBLE);

        return false;
    }

    @Override
    public boolean onQueryTextChange(String newText) {

        initAdapter(newText);

        return true;
    }

    public void initAdapter(String text) {

        //tabLayout.setVisibility(View.INVISIBLE);
        //RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) tabLayout.getLayoutParams();
        //params.addRule(RelativeLayout.BELOW, R.id.listview);
        //tabLayout.setLayoutParams(params);
        appBarLayout.setVisibility(View.INVISIBLE);
        adapter_search = new FriendListAdapter(this,listUsers);
        listview.setVisibility(View.VISIBLE);
        listview.bringToFront();
        listview.setAdapter(adapter_search);
        //adapter_search.filter(text);
        adapter_search.getFilter().filter(text);
    }

    public static <V extends View> Collection<V> findChildrenByClass(ViewGroup viewGroup, Class<V> clazz) {

        return gatherChildrenByClass(viewGroup, clazz, new ArrayList<V>());
    }

    private static <V extends View> Collection<V> gatherChildrenByClass(ViewGroup viewGroup, Class<V> clazz, Collection<V> childrenFound) {

        for (int i = 0; i < viewGroup.getChildCount(); i++)
        {
            final View child = viewGroup.getChildAt(i);
            if (clazz.isAssignableFrom(child.getClass())) {
                childrenFound.add((V)child);
            }
            if (child instanceof ViewGroup) {
                gatherChildrenByClass((ViewGroup) child, clazz, childrenFound);
            }
        }

        return childrenFound;
    }

    public void finalize_search(UserProject user) {

        if (!newList.contains(user) && !listOwners.contains(user)) {
            if (user_type == 1) {
                UserProject.addUserUniqueTag(newList, user, UserTag.COLLABORATOR);
            } else if (user_type == 2) {
                UserProject.addUserUniqueTag(listOwners, user, UserTag.OWNER);
            }
        }
        else {
            if (user_type == 1) {
                //UserProject.addUserUniqueTag(newList, user, UserTag.COLLABORATOR);
                newList.remove(user);
                UserProject.addUserUniqueTag(removedColab, user, UserTag.COLLABORATOR);
            } else if (user_type == 2) {
                //UserProject.addUserUniqueTag(listOwners, user, UserTag.OWNER);
                listOwners.remove(user);
                UserProject.addUserUniqueTag(removedOwner, user, UserTag.OWNER);
            }
        }
        ExternsFragment.teamAdapter.notifyDataSetChanged();
        searchMenuItem.collapseActionView();
        searchView.onActionViewCollapsed();
        viewPager.bringToFront();
        listview.setVisibility(View.GONE);
        appBarLayout.setVisibility(View.VISIBLE);

    }

点击我的适配器中的一个项目后,我调用finalize_search()

这是泄漏金丝雀的报告:

enter image description here

enter image description here

答案

当我让android工具栏为我驱动我的searchView时,我遇到了类似的问题。看起来像是在进行多个Searchview并在扩展和折叠时导致调整大小问题。

我通过在代码中管理它来解决问题。我真的不喜欢这个解决方案,但它确实是我遇到这些问题的唯一方法。希望它也能帮到你。

 private void setupSearchView(){
    if(getActivity() == null){
        return;

    }

    mSearchView = new SearchView(mBaseActivityCallback.getSupportToolBar().getThemedContext());
    mSearchView.setIconifiedByDefault(false);
    mBaseActivityCallback.getSupportToolBar().setCustomView(mSearchView);
    mBaseActivityCallback.getSupportToolBar().setDisplayShowCustomEnabled(true);
    mSearchView.setFocusable(false);
    int id = mSearchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
    TextView textView = (TextView) mSearchView.findViewById(id);
    textView.setHintTextColor(Color.GRAY);
    mSearchView.setQueryHint(getString(R.string.hint_entry));


    //Retrieves the system search manager service
    final SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);


    mSearchView.clearFocus();
    //Assign searchable info to SearchView
    mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));

    //Set Listeners
    searchView_onQueryText(mSearchView);

    //Set query as order number if it has been set
    if(orderQuery != null){
        mSearchView.setQuery(orderQuery, false);

    }
}

以上是关于SearchView在Android应用中泄漏内存的主要内容,如果未能解决你的问题,请参考以下文章

Android应用程序内存泄漏介绍

Android应用程序内存泄漏介绍

Android 常见内存泄漏的解决方式

Android性能优化之内存泄漏

Android 应用程序中的内存泄漏

Android:如何测试应用程序中的内存泄漏?