1

I try to do it like this: Decompress Rar file in Android

But one of my rar file cannot be decompressed.

Logs:

01-01 17:41:32.121: E/AndroidRuntime(12799): FATAL EXCEPTION: Thread-771
01-01 17:41:32.121: E/AndroidRuntime(12799): java.lang.OutOfMemoryError
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.ppm.SubAllocator.startSubAllocator(SubAllocator.java:146)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.ppm.ModelPPM.decodeInit(ModelPPM.java:216)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.Unpack.readTables(Unpack.java:656)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.Unpack.unpack29(Unpack.java:165)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.Unpack.doUnpack(Unpack.java:120)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.Archive.doExtractFile(Archive.java:500)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.Archive.extractFile(Archive.java:442)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.testutil.ExtractArchive.extractArchive(ExtractArchive.java:73)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.testutil.ExtractArchive.extractArchive(ExtractArchive.java:29)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.letusread.util.DeCompressUtil.deCompress(DeCompressUtil.java:140)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.letusread.activity.FileListActivity$7.run(FileListActivity.java:338)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at java.lang.Thread.run(Thread.java:856)
01-01 17:41:32.324: E/MobclickAgent(12799): onEndSession called before onStartSession

I the file was decompressed but my apps has crashed! other files can be decompressed properly; can you help me to solve this error??

Community
  • 1
  • 1
Stilo
  • 23
  • 2

2 Answers2

0

It seems that problem is in allocating heap memory for extracting files. You can see that there is OutOfMemoryError on line 146 in file SubAllocator.java. On this line is byte array initialized:

heap = new byte[realAllocSize];

Apparently variable realAllocSize is bigger than avaliable free memory which is on heap in bytes. On Android devices is heap size usualy 32 or 64 MB for each VM (each activity has own VM). It seems that problem is in junrar library which is not optimized to use on Android devices and consumes lot of memory.

tomasbuzek
  • 526
  • 3
  • 13
  • yes,I just checked the source,but would you have any good way? – Stilo Jan 01 '13 at 10:45
  • I would try to decide how much memory is junrar library consuming. If it is far more than avaliable heap memory is it would be better to find another library for rar decompressing. But if library allocated memory is only few MB maybe the problem is in another part of your application which is consuming too much memory. – tomasbuzek Jan 01 '13 at 10:56
  • you see,most of rar files can be decompressed successfully,but only a few of them throws outofmemory exception.that's why I can't understand. – Stilo Jan 01 '13 at 15:21
  • As I checked junrar source code I think that allocation of heap memory for extracting files is dependent on some information from rar file header. That should explain that some files are succesfully extracted while some are not. Maybe it could depend on level of compression or on some other property which are different in headers of different rar files. – tomasbuzek Jan 01 '13 at 15:35
  • Oh,but some of other apps can easily decompress this rar file,I'm trying to solve the problem. – Stilo Jan 01 '13 at 16:00
0

In fact, it seems to be a bug of the implementation. This is the workaround I have used in order to avoid the problem:

In com.github.junrar.unpack.ppm.ModelPPM.java, line 196: MaxMB = unpackRead.getChar();

the method getChar, in some weird situations, return a very big number. It should be due to a broken header or a header option not supported by junrar.

My workaround was to check if MaxMB was greater than 1 and set to 1. I've been using this fix for a long time without problems.

int MaxMB = 0;
if (reset) {
    MaxMB = unpackRead.getChar();
    if (MaxMB > 1) { //Workaround
        MaxMB = 1;
    }
}
Davide Pastore
  • 8,678
  • 10
  • 39
  • 53
yopablo
  • 68
  • 6