KonifarPod

Android2でインストール時にINSTALL_FAILED_DEXOPTエラー

   

Pocket

ビルドしたアプリをAndroid2の端末にインストールしようとしたら、INSTALL_FAILED_DEXOPT というエラーでインストールできませんでした。ビルドはできますし、Android4は全く問題ありません。Android2の端末だけダメでした。

pkg: /data/local/tmp/com.konifar
Failure [INSTALL_FAILED_DEXOPT]

 

1. 原因

調べてみたところ、Facebookエンジニアのノートに詳しい原因が書いてありました。

 

During standard installation, a program called “dexopt” runs to prepare your app for the specific phone it’s being installed on. Dexopt uses a fixed-size buffer (called the “LinearAlloc” buffer) to store information about all of the methods in your app. Recent versions of Android use an 8 or 16 MB buffer, but Froyo and Gingerbread (versions 2.2 and 2.3) only have 5 MB. Because older versions of Android have a relatively small buffer, our large number of methods was exceeding the buffer size and causing dexopt to crash. 

 

どうやら通常のインストール時には『dexopt』というプログラムが実行されるらしく、その処理はすべてのメソッドの情報を一定サイズの領域に貯めこむらしいです。Android4以上の最近のバージョンだと8MB、16MBの領域が確保されているのですが、Android2.3以下のOSでは5MBしかなく、それに収まりきらないほどたくさんのメソッド数だとdexoptがクラッシュしてインストールエラーになるとのことです。

アプリ内のメソッドだけでなく、インポートしたライブラリも含めたメソッド数なので、ちょっとライブラリを追加していくとすぐに限界に来てしまいます。。

 

2. 対処

じゃあどうするかという話ですが、先ほどのリンクを見てみるとFacebookもいくつかやり方を試してみたらしいです。詳しくは見ていただきたいのですが、カスタムクラスローダーを作ったりとちょっと面倒そうで、すぐ解決できるという感じじゃありませんでした。また、Proguardを使って必要なメソッドだけapkに入れるというのもすでにやっていましたので、他の方法を考えなければなりませんでした。

 

どうしようかなと悩みながら色々見てみると、build.gradleの依存関係の無駄がありそうということに気づきました。余計なライブラリをインポートしていたというわけです。

具体的に言うと、support-v4-13.0.0 と support-v4-13.1.0 が両方インポートされていました。これは片方だけでいいはず・・・と思い、build.gradleのコンパイル部分にexcludeオプションをつけてsupportライブラリをダウンロードしないようにしてみました。

 

compile ('com.aviary.android.feather.sdk:aviary-sdk:3.4.3.351') {
    exclude module: 'support-v4'
}

 

こんな感じのオプションを依存するライブラリすべてに追加してみたところ、メソッド数が制限内に収まったようで、Android2でもインストールできました。

さらっと書きましたが、この単純な結果に行き着くまでに1日かかりました。。。これちゃんと対応するならどうすべきなんでしょうか。ライブラリを追加するたびにヒヤヒヤするのは嫌なので、早めに恒久対応をしておきたいです。対応できたらまたメモに残しておこうと思います。

 

Pocket

 - Develop