2017-08-17 8 views
0

SeekableInMemoryByteChannelクラスをApache commons-compressパッケージから使用しようとすると、アプリケーションはjava.lang.NoClassDefFoundError: org.apache.commons.compress.utils.SeekableInMemoryByteChannel例外を発生してクラッシュします。Apache Commons Compressが解決できないAndroid Nより前のSeekableInMemoryByteChannel

特に興味深いのは、少なくとも私にとっては、Android 7以降を実行しているデバイスでは発生していないが、他のすべてのバージョンで問題が発生していることです。具体的には、私はこの問題がAndroid 6.0.1,6.0,5.1.1で発生することを確認しましたが、はAndroid 7.0または7.1.1ではが発生しません。これらのデバイスはそれぞれ異なるベンダーから提供されています。

私はゴーストクラスの重大なケースに直面しています。最初は、私のアプリがMultiDexを使用していたこと、またはビルドプロセスが正しく設定されていなかったことに関連していると考えました。しかし、これらの機能を持たない全く新しいプロジェクトでも同じことが起こります。同じパッケージから別のクラスを使用しようとしましたが、それらは正常に解決されています。私はProGuardにパッケージを追加しましたが、運はありません。

これは、問題を複製コードです:

package lt.kaz.compresstest; 

import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry; 
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; 

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     ZipArchiveEntry zipEntry = new ZipArchiveEntry("hello"); 
     zipEntry.setSize(600); 

     SevenZArchiveEntry sevenZipEntry = new SevenZArchiveEntry(); 
     sevenZipEntry.setName("sevenZip"); 

     try { 
      MainActivity.class.getClassLoader().loadClass("org.apache.commons.compress.utils.ChecksumCalculatingInputStream"); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 

     SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel(new byte[]{5, 10, 15, 10}); 
     // App never gets here prior to Android N 
     Log.d("lt.kaz", channel.toString()); 
    } 
} 

...とGradleのファイル...

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 26 
    buildToolsVersion "26.0.1" 
    defaultConfig { 
     applicationId 'lt.kaz.compresstest' 
     minSdkVersion 19 
     targetSdkVersion 25 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
    productFlavors { 
    } 
} 

dependencies { 
    compile fileTree(include: ['*.jar'], dir: 'libs') 
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
     exclude group: 'com.android.support', module: 'support-annotations' 
    }) 
    compile 'com.android.support:appcompat-v7:26.+' 
    compile 'com.android.support.constraint:constraint-layout:1.0.2' 
    compile 'com.android.support:design:26.+' 
    compile 'org.apache.commons:commons-compress:1.14' 
    testCompile 'junit:junit:4.12' 
} 

...とProGuardの...

-keep public class org.apache.commons.compress 

本当にありがとうございます。そのような行動の理由は何でしょうか?どのように解決することができますか?

答えて

0

明らかに、java.nio.channelsパッケージのインターフェイスは、のAndroid APIレベル24(したがってアンドロイドN)からのものです。

私の最終的な解決策は、元の意図がクラスを使用することだったので、その実装ではSeekableByteChannelクラスを使用しないため、commons-compressをバージョン1.12にダウングレードすることでした。

関連する問題