【问题标题】:Getting Memory leak on android fragment在android片段上获取内存泄漏
【发布时间】:2015-05-07 21:47:23
【问题描述】:

我一直在寻找我的 android 应用程序上的“内存泄漏”问题的解决方案,但是,事情是这样的:
我在 viewpager 中加载了一个片段,这个片段有一个 Gridview 和一个适配器(ArrayAdapter),它创建了 gridview 的每个项目,这些项目有一个图像和一些文本(我使用 Universal Image Loader 来加载图像。 )

当我更改设备方向时出现大量内存泄漏。

  • 我已将所有适配器上下文更改为 ApplicationContext。
  • 我已将图像加载器插件(通用图像加载器)更改为 Picasso
  • 我已将 ArrayAdapter 更改为 BaseAdapter。
  • 我已将 Gridview 更改为 FlowLayoutView,并将所有项目作为 View 添加到这个新的 ViewGroup。
  • 还没有使用 android 进行“调试”测试。

这些更改没有一个起作用,我仍然遇到内存泄漏,所以,欢迎任何帮助!

编辑:

public class MoviesFragment extends Fragment {

public MoviesFragment() {
}

final String TAG = MoviesFragment.class.toString();
ExpandableHeightGridView movieGridView;
MovieAdapter mMovieAdapter;
ArrayList<Movie> movies;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle args = getArguments();
    movies = args.getParcelableArrayList("movies");
    mMovieAdapter = new MovieAdapter(getActivity().getApplicationContext(), movies);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.fragment_movies, container, false);
    movieGridView = (ExpandableHeightGridView) rootView.findViewById(R.id.gridview_movies);

    if (movies != null) {

        movieGridView.setAdapter(mMovieAdapter);
        movieGridView.setExpanded(true);
        movieGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                EventBus.getDefault().post(
                        new EventSelectedEvent((Movie) parent.getItemAtPosition(position)));
            }
        });
    } else {
        movieGridView.setExpanded(false);
    }
    return rootView;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

}

}

public class MovieAdapter extends ArrayAdapter<Movie> {

Context context;

public MovieAdapter(Context context, List<Movie> movies) {
    super(context, 0, movies);
    this.context = context.getApplicationContext();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Get the data item for this position
    Movie movie = getItem(position);
    // Check if an existing view is being reused, otherwise inflate the view
    if (convertView == null) {
        convertView = LayoutInflater.from(getContext().getApplicationContext()).inflate(R.layout.layout_card_movies, parent, false);
    }
    // Lookup view for data population
    TextView movieName = (TextView) convertView.findViewById(R.id.card_movie_text);

    //Load square image
    Image squareImg = movie.getSquareImage();
    if (null != squareImg) {
        ImageLoader iLoader = ImageLoaderHandler.getImageLoader(TandasApplication.getInstance());
        iLoader.displayImage(squareImg.getLink(),
                (ImageView) convertView.findViewById(R.id.card_movie_image));
    }

    //Title
    movieName.setText(movie.getTitle());

    //Rating
    LinearLayout ratingContainer = (LinearLayout) convertView.findViewById(R.id.ratingMovieMainView);
    double rating = movie.getRating();
    UIUtils.buildRatingStars(rating, ratingContainer, context);

    // Return the completed view to render on screen
    return convertView;
}

}

【问题讨论】:

    标签: android gridview android-fragments memory-leaks android-arrayadapter


    【解决方案1】:

    没有太多信息可以继续,我认为您正在坚持您的片段引用。

    使用 adb shell 命令 dumpsys 对此进行测试

    adb shell dumpsys activity <package_name>
    adb shell dumpsys meminfo <package_name>
    

    浏览各种片段并在每次浏览其中一个片段后运行它。 Meminfo 会告诉你应用程序正在举行多少活动。活动为您分解一切。

    如果您发布一些日志或代码,我可以更好地帮助您。

    【讨论】:

    • 嗨,我发布了一些代码,当我改变设备方向时,MoviesFragment onCreateView 正在设置一个新的适配器。
    • 这个:this.context = context.getApplicationContext();可以产生泄漏。您不希望您的适配器使用应用程序上下文,而是使用活动上下文。
    • 最好不要保留对上下文的引用 - 您可以在使用它的地方使用 convertView.getContext()。
    • 你是对的,最好不要保留对上下文的引用,但是你不想使用 convertView.getcontext() 因为它可以为空。相反,您想使用 parent.getContext() 因为 parent 永远不会为空。
    猜你喜欢
    • 2013-11-30
    • 2019-12-22
    • 1970-01-01
    • 2015-07-20
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多