我正在开发一个应用程序,其中我的主页面是网格视图,我从服务器获取缩略图图像。当用户单击主活动上的图像时,它会获取项目的位置并调用另一个URL来加载单个完整大小的图像并加载到详细活动中。我只需使用后退按钮在主要活动和详细活动之间前进即可。我已完成此步骤8-9次,我的应用程序崩溃,它抛出内存(OOM)。
我的全尺寸图像在30 kb到115 kb之间变化。缩略图图像的变化范围为20 kb到45 kb。
java.lang.RuntimeException:执行时发生错误 doInBackground()
我在详细活动中使用Volley和我的图像加载如下。
在以下代码中,我检索单击的产品json对象,它包含相应的完整大小图像的URL。
在主要活动中检索详细信息产品JSON对象。
StringRequest postRequest = new StringRequest(Request.Method.POST, Config.PRODUCT_DETAIL_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
Intent intent = new Intent(MainActivity.this, ProductDetailActivity.class);
intent.putExtra("jsonArray", response);
MainActivity.this.startActivity(intent);
MainActivity.this.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}
) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("id", productid);
return params;
}
}
我将JSON对象从主活动发送到详细活动,如下所示intent.putExtra("jsonArray", response);
并获取图像URL并在ImageView中显示如下。
在DetailActivity中
String MY_URL_STRING = Config.IMAGE_PATH_URL+"/"+obj.optString("pimagePath");
new DownloadImageTask((ImageView) findViewById(R.id.detailImage))
.execute(MY_URL_STRING);
DownloadImageTask Class
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
CustomVolley请求
private CustomVolleyRequest(Context context) {
this.context = context;
this.requestQueue = getRequestQueue();
imageLoader = new ImageLoader(requestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized CustomVolleyRequest getInstance(Context context) {
if (customVolleyRequest == null) {
customVolleyRequest = new CustomVolleyRequest(context);
}
return customVolleyRequest;
}
public RequestQueue getRequestQueue() {
if (requestQueue == null) {
Cache cache = new DiskBasedCache(context.getCacheDir(), 10 * 1024 * 1024);
Network network = new BasicNetwork(new HurlStack());
requestQueue = new RequestQueue(cache, network);
requestQueue.start();
}
return requestQueue;
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
我在监视内存的同时测试了应用程序,我观察到内存已分配并且从未释放回来,即使我不再看那个图像了。它不断增加。对不起,我来自iOS方面,相对较新的Android,并不了解内存管理。
内存监控,每次点击都会增加,当我回到主要活动时它会释放内存!
堆栈追踪:
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask E/AndroidRuntime:
Process: PID: 5700
java.lang.RuntimeException: An error occured while executing
doInBackground() E/AndroidRuntime: at
android.os.AsyncTask$3.done(AsyncTask.java:300) E/AndroidRuntime: at
java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
E/AndroidRuntime: at
java.util.concurrent.FutureTask.setException(FutureTask.java:222)
E/AndroidRuntime: at
java.util.concurrent.FutureTask.run(FutureTask.java:242)
E/AndroidRuntime: at
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
E/AndroidRuntime: at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/AndroidRuntime: at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/AndroidRuntime: at java.lang.Thread.run(Thread.java:841)
E/AndroidRuntime: Caused by: java.lang.OutOfMemoryError
E/AndroidRuntime: at
android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
E/AndroidRuntime: at
android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:613)
E/AndroidRuntime: at
android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:589)
E/AndroidRuntime: at
android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:627)
E/AndroidRuntime: at
com.example.xxx.xxx.DownloadImageTask.doInBackground(DownloadImageTask.java:26)
E/AndroidRuntime: at
com.example.xxx.xxx.DownloadImageTask.doInBackground(DownloadImageTask.java:14)
E/AndroidRuntime: at
android.os.AsyncTask$2.call(AsyncTask.java:288)
E/AndroidRuntime: at
java.util.concurrent.FutureTask.run(FutureTask.java:237)
E/AndroidRuntime: at
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
E/AndroidRuntime: at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/AndroidRuntime: at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/AndroidRuntime: at java.lang.Thread.run(Thread.java:841)