Reputation: 664
I make this app for school and need to hand it in tomorrow. Little problem, it keeps crashing at a certain point.
My app downloads a .zip from Firebase and unzips it:
-- Cache directory
--images
--image01.jpg
--image02.jpg
--image03.jpg
--and so on...
--info.txt
--scan234702640.zip // this is the file that includes the /images and the info.txt
So I have the following code in my class imageHandler:
// Get the file
gsReference.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
String path = "";
File f = new File(context.getExternalCacheDir().toURI());
File[] files1 = f.listFiles();
for (File inFile1 : files1) {
if (inFile1.getName().contains("scan")) {
path = context.getExternalCacheDir() + "/" + inFile1.getName();
}
}
//Decompress zip and build bitmap array
try {
ZipFile zip = new ZipFile(path);
zip.extractAll(context.getExternalCacheDir() + "/");
} catch (ZipException e){
Toast.makeText(context, "ZIP error " + e.getCode() + " : " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
//Construct bitmap array
ArrayList<Bitmap> pictures = new ArrayList<Bitmap>();
File f3 = new File(context.getExternalCacheDir().toString() + "/images/");
if (f3.exists()) {
File[] files3 = f3.listFiles(); //THE PROBLEM IS SOMEWHERE HERE
if (files3 != null) {
for (File inFile3 : files3) {
if (inFile3.exists()) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(inFile3.getPath(), options);
pictures.add(bitmap);
}
}
}
}
// DEBUG: Show what we have in our cache location
String message = "";
File f2 = new File(context.getExternalCacheDir().toURI() + "/images");
File[] files2 = f2.listFiles();
for (File inFile2 : files2) {
if (inFile2.isDirectory()) {
message += "/" + inFile2.getName() + "\n";
} else {
message += inFile2.getName() + "\n";
}
}
AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle("Test Message")
.setMessage(message)
.show();
// END OF DEBUG
}
});
return scan;
So, it crashes at the part where it says "THE PROBLEM IS SOMEWHERE HERE". I have asked all EXTERNAL_STORAGE permissions and I've checked if the files exist. I found out, in debug mode, that it successfully adds the bitmaps to the array, but when I have for example 10 images, it crashes after it loaded all 10 in. So pls help me ;)
Thx a lot, Jules
EDIT Here is the console log:
10-31 00:07:31.060 7536-7536/com.julescitronic.meeting E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.julescitronic.meeting, PID: 7536
java.lang.NullPointerException: Attempt to get length of null array
at com.julescitronic.meeting.imageHandler$2.onSuccess(imageHandler.java:152)
at com.julescitronic.meeting.imageHandler$2.onSuccess(imageHandler.java:127)
at com.google.firebase.storage.StorageTask$1.zza(Unknown Source:9)
at com.google.firebase.storage.StorageTask$1.zzl(Unknown Source:4)
at com.google.firebase.storage.zze$2.run(Unknown Source:10)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Upvotes: 0
Views: 6350
Reputation: 1051
listFiles();
is a file permission, I was getting similar crash in my code on Android API 23 and above (as file storage permission is required during runtime), so I provided same as follow :
if (Build.VERSION.SDK_INT >= 23) {
if (AppMain.mContext.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission is granted");
return true;
} else {
ActivityCompat.requestPermissions(activityContext, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
After this I didn't get null pointer on listFile operation.
Upvotes: 1
Reputation: 557
I found out, in debug mode, that it successfully adds the bitmaps to the array, but when I have for example 10 images, it crashes after it loaded all 10 in.
Based on your last sentence, I believe that you have memory issues rather than permission issues.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(inFile3.getPath(), options);
pictures.add(bitmap);
With this code you load each bitmap in its full size and add it to a list of bitmaps, depriving GC to free the native object associated with the bitmap. This can be a big problem if you load an image with let's say 10 MB * 10 images. That will easily lead to memory issues.
I would suggest to load the bitmaps more efficiently. This would mean, that you load a downsampled bitmap into memory and use that one, since having a Bitmap with size for example 3000x4000 makes no sense if it will be displayed on an ImageView with size 512x384. This link is a good guide and can be of help:
https://developer.android.com/topic/performance/graphics/load-bitmap.html
Upvotes: 0