使用多个线程下载图像会导致 OutOfMemory 异常
Downloading images with multiple Threads causes an OutOfMemory Exception
我正在检索图像名称的字符串并且必须从服务器下载位图
要从 JSON 数据中获取图像名称字符串并使用此 link 进行下载:
String str_ImgURL_bmp_pattern = "http://xxxx/xxx/MobileService.svc/DownloadFile/FileName/" + imageName;
download_PngFile(str_ImgURL_bmp_pattern);
void download_PngFile(String fileUrl) {
Log.e("In download_PngFile ", " str_imgList_imageaudioPath = " + imageName);
Bitmap imagenObtenida = null;
try {
URL ImgUrl = new URL(fileUrl);
HttpURLConnection conn = (HttpURLConnection) ImgUrl.openConnection();
conn.connect();
imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream());
//Log.e("imagenObtenida", " = " + imagenObtenida);
String fotoname = imageName;
File file = new File(newFolder, fotoname);
int sizeOfImage = (int) file.length();
Log.e("sizeOfImage ", " = " + sizeOfImage + "@ " + imageName);
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
imagenObtenida.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
// Log.e("Png = ", "DownLoad complete");
} catch (Exception e) {
}
} catch (IOException e) {
e.printStackTrace();
}
}
但是有些图片是下载的,有时应用程序崩溃了,我在 logcat 的标题中得到了错误。
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:278)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:549)
at com.example.tazeen.classnkk.AllPosts_Page.download_PngFile(AllPosts_Page.java:896)
at com.example.tazeen.classnkk.AllPosts_Page.getDoenLoaddata(AllPosts_Page.java:820)
at com.example.tazeen.classnkk.AllPosts_Page$GetgetAllImagePath_List.doInBackground(AllPosts_Page.java:781)
at com.example.tazeen.classnkk.AllPosts_Page$GetgetAllImagePath_List.doInBackground(AllPosts_Page.java:771)
at android.os.AsyncTask.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
这一行的错误:imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream());
如何解决这个问题。
所以基本上异常是很清楚的。
你的记忆力不足。
有一些可能的解决方案:
1.缩小图像:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream(), null, options);
这是必需的,即使是单个图像下载也会导致崩溃。
2。不同时解码
所以不要使用 ThreadPoolExecutor
3。组合
例如:
-只需使用 2 个并行线程
-检查可用内存并设置适合当前内存的线程数
-捕获内存不足异常并等待其他线程完成
我正在检索图像名称的字符串并且必须从服务器下载位图 要从 JSON 数据中获取图像名称字符串并使用此 link 进行下载:
String str_ImgURL_bmp_pattern = "http://xxxx/xxx/MobileService.svc/DownloadFile/FileName/" + imageName; download_PngFile(str_ImgURL_bmp_pattern);
void download_PngFile(String fileUrl) {
Log.e("In download_PngFile ", " str_imgList_imageaudioPath = " + imageName);
Bitmap imagenObtenida = null;
try {
URL ImgUrl = new URL(fileUrl);
HttpURLConnection conn = (HttpURLConnection) ImgUrl.openConnection();
conn.connect();
imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream());
//Log.e("imagenObtenida", " = " + imagenObtenida);
String fotoname = imageName;
File file = new File(newFolder, fotoname);
int sizeOfImage = (int) file.length();
Log.e("sizeOfImage ", " = " + sizeOfImage + "@ " + imageName);
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
imagenObtenida.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
// Log.e("Png = ", "DownLoad complete");
} catch (Exception e) {
}
} catch (IOException e) {
e.printStackTrace();
}
}
但是有些图片是下载的,有时应用程序崩溃了,我在 logcat 的标题中得到了错误。
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:278)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:549)
at com.example.tazeen.classnkk.AllPosts_Page.download_PngFile(AllPosts_Page.java:896)
at com.example.tazeen.classnkk.AllPosts_Page.getDoenLoaddata(AllPosts_Page.java:820)
at com.example.tazeen.classnkk.AllPosts_Page$GetgetAllImagePath_List.doInBackground(AllPosts_Page.java:781)
at com.example.tazeen.classnkk.AllPosts_Page$GetgetAllImagePath_List.doInBackground(AllPosts_Page.java:771)
at android.os.AsyncTask.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
这一行的错误:imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream());
如何解决这个问题。
所以基本上异常是很清楚的。 你的记忆力不足。
有一些可能的解决方案:
1.缩小图像:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream(), null, options);
这是必需的,即使是单个图像下载也会导致崩溃。
2。不同时解码
所以不要使用 ThreadPoolExecutor
3。组合 例如:
-只需使用 2 个并行线程
-检查可用内存并设置适合当前内存的线程数
-捕获内存不足异常并等待其他线程完成