在 android 片段上发生内存泄漏
Getting Memory leak on android fragment
我一直在寻找 android 应用程序中 "memory leaks" 问题的解决方案,但问题是:
我正在 viewpager 中加载一个片段,这个片段有一个 Gridview 和一个创建 gridview 的每个项目的适配器 (ArrayAdapter),这些项目有一个图像和一些文本(我正在使用 Universal Image Loader,加载图片。)
当我改变设备方向时,我遇到了很多内存泄漏。
- 我已将所有适配器上下文更改为 ApplicationContext。
- 我已将图像加载器插件 (Universal Image Loader) 更改为
Picasso.
- 我已将 ArrayAdapter 更改为 BaseAdapter。
- 我已将 Gridview 更改为 FlowLayoutView,并将所有项目作为视图添加到这个新的 ViewGroup。
- 也在没有 "debugging" 和 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;
}
}
没有太多信息可以继续,我认为你坚持你的片段参考。
使用 adb shell 命令 dumpsys
进行测试
adb shell dumpsys activity <package_name>
adb shell dumpsys meminfo <package_name>
浏览各种片段,然后 运行 每次浏览其中一个片段后执行此操作。 Meminfo 会告诉您应用程序正在进行多少活动。 Activity 为你分解一切。
如果你post一些日志或代码,我可以更好地帮助你。
我一直在寻找 android 应用程序中 "memory leaks" 问题的解决方案,但问题是:
我正在 viewpager 中加载一个片段,这个片段有一个 Gridview 和一个创建 gridview 的每个项目的适配器 (ArrayAdapter),这些项目有一个图像和一些文本(我正在使用 Universal Image Loader,加载图片。)
当我改变设备方向时,我遇到了很多内存泄漏。
- 我已将所有适配器上下文更改为 ApplicationContext。
- 我已将图像加载器插件 (Universal Image Loader) 更改为 Picasso.
- 我已将 ArrayAdapter 更改为 BaseAdapter。
- 我已将 Gridview 更改为 FlowLayoutView,并将所有项目作为视图添加到这个新的 ViewGroup。
- 也在没有 "debugging" 和 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;
}
}
没有太多信息可以继续,我认为你坚持你的片段参考。
使用 adb shell 命令 dumpsys
进行测试adb shell dumpsys activity <package_name>
adb shell dumpsys meminfo <package_name>
浏览各种片段,然后 运行 每次浏览其中一个片段后执行此操作。 Meminfo 会告诉您应用程序正在进行多少活动。 Activity 为你分解一切。
如果你post一些日志或代码,我可以更好地帮助你。