gpt4 book ai didi

java - Android 图像 GridView 消耗所有内存并崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 14:10:17 26 4
gpt4 key购买 nike

我正在尝试调试应用程序中消耗所有内存并导致应用程序崩溃的位置。

它全部加载查找,但当我向下滚动 GridView 时,我将更多图像加载到 GridView 中,一切正常。如果我向后滚动,我可以看到它们正在从缓存中加载。但当我继续向下滚动时,设备分配了大约 250mb 的空间并崩溃了。任何我出错的地方的想法。

我可能还应该注意到,当这个 Gird 崩溃时,它大约有 150 个图像(每个大约 20kb)。我希望能得到更多。

请温柔一点,我是 Java 和 Android 新手。

项目适配器

public ItemAdapter(Context context, int resource, List<Item> objects) {
super(context, resource, objects);
this.context = context;
this.itemList = objects;

final int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
imageCache = new LruCache<>(cacheSize);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.feed_staggered_grid_view_item, parent, false);

//Display item name in textview widget
Item item = itemList.get(position);
TextView item_title = (TextView) view.findViewById(R.id.textView1);
item_title.setText(item.getTitle());

TextView item_brand = (TextView) view.findViewById(R.id.textView2);
item_brand.setText(item.getBrand());

//display image
Bitmap bitmap = imageCache.get(item.getItemId());
if (bitmap != null) {
ImageView image = (ImageView) view.findViewById(R.id.imageView);
image.setImageBitmap(bitmap);
} else {
ItemAndView container = new ItemAndView();
container.item = item;
container.view = view;

ImageLoader loader = new ImageLoader();
loader.execute(container);
}

return view;
}

class ItemAndView {
public Item item;
public View view;
public Bitmap bitmap;
}

private class ImageLoader extends AsyncTask<ItemAndView, Void, ItemAndView> {

@Override
protected ItemAndView doInBackground(ItemAndView... params) {
ItemAndView container = params[0];
Item item = container.item;

try {
StringBuilder sb = new StringBuilder();
sb.append(FeedFragment.IMAGES_BASE_URL);
sb.append(item.getCategory());
sb.append("/");
sb.append(item.getProductId());
sb.append("/img1.jpg");
String imageUrl = sb.toString();

InputStream in = (InputStream) new URL(imageUrl).getContent();
Bitmap bitmap = BitmapFactory.decodeStream(in);
item.setBitmap(bitmap);
in.close();
container.bitmap = bitmap;
return container;
} catch (Exception e){
e.printStackTrace();
}
return null;
}

@Override
protected void onPostExecute(ItemAndView itemAndView) {
ImageView image = (ImageView) itemAndView.view.findViewById(R.id.imageView);
image.setImageBitmap(itemAndView.bitmap);
if (imageCache.get(itemAndView.item.getItemId()) == null) {
imageCache.put(itemAndView.item.getItemId(), itemAndView.bitmap);
}
}
}

提要 fragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (feedItemList == null) {
requestData(FEED_BASE_URL + pageNum);
}
return inflater.inflate(R.layout.feed_staggered_grid_view, container, false);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (feedItemList != null) {
updateDisplay();
}
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}

private void requestData(String uri) {
MyTask task = new MyTask();
task.execute(uri);
pageNum++;
}

protected void updateDisplay() {
feedAdapter = new ItemAdapter(getActivity(), R.layout.feed_staggered_grid_view_item, feedItemList);
feedGridView = (StaggeredGridView) getView().findViewById(R.id.grid_view);
feedGridView.setAdapter(feedAdapter);
feedGridView.setOnScrollListener(this);
feedGridView.setOnItemClickListener(this);
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (!isLoading && totalItemCount != 0) {
int lastItemInScreen = firstVisibleItem + visibleItemCount;
if (lastItemInScreen >= totalItemCount) {
isLoading = true;
requestData(FEED_BASE_URL + pageNum);
}
}
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Item item = feedItemList.get(position);
Intent intent = new Intent(getSherlockActivity(), ItemViewer.class);

Bundle extras = new Bundle();
extras.putString("item_title", item.getTitle());
extras.putString("item_description", item.getDescription());
extras.putString("item_brand", item.getBrand());
extras.putDouble("item_price", item.getPrice());
extras.putString("item_photo", item.getPhoto());
intent.putExtras(extras);

startActivity(intent);
}

private class MyTask extends AsyncTask<String, String, List<Item>> {

@Override
protected void onPreExecute() {
}

@Override
protected List<Item> doInBackground(String... params) {
String content = HttpManager.getData(params[0]);
List<Item> data = ItemFeedJSONParser.parseFeed(content);
if (feedItemList == null) {
feedItemList = data;
} else {
feedItemList.addAll(data);
}

return null;
}

@Override
protected void onPostExecute(List<Item> result) {
if (pageNum <= 1) {
updateDisplay();
} else {
feedAdapter.notifyDataSetChanged();
}

isLoading = false;

}
}

这是错误消息

 FATAL EXCEPTION: AsyncTask #5
Process: com.test.game.test, PID: 10931
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 429212 byte allocation with 80604 free bytes and 78KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:649)
at com.test.game.adapters.ItemAdapter$ImageLoader.doInBackground(ItemAdapter.java:106)
at com.test.game.adapters.ItemAdapter$ImageLoader.doInBackground(ItemAdapter.java:89)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
     at java.lang.Thread.run(Thread.java:818)

最佳答案

这里的问题是您加载的位图太大。不仅图像的下载而且放置也应该在后台完成。使用 AsyncTask 来执行此操作,或者您始终可以使用 PicassoIon 。我也遇到过同样的问题,用 Ion 解决了,效果很好。

此外,不要为每一项加载不同的 View ,请使用convertView。

关于java - Android 图像 GridView 消耗所有内存并崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28409861/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com