3

うまくいけば、これは長すぎることではありませんが、完全にしようとしています:

だから私はAndroidマーケットにアプリを持っています。アプリ内には、いくつかのシリアライズ可能なクラスがあります。アプリはどこでも正常に動作しています (エミュレーター、デバッグ電話、アプリをダウンロードする電話)。

いくつかの機能を追加することにしました。これらの機能には、私の Serializable クラスの 1 つに Comparable を実装することが含まれます。Eclipse (エミュレーターまたは接続された電話) では、変更は有効に見えます。また、このJavaドキュメントによると、変更はSerializableクラスへの有効な変更だと思います。

今問題に。署名済み apk をエクスポートした後、アプリがクラッシュしたようです。クラッシュは、変更されたクラスに初めて触れたときに発生します。スタック トレースは難読化されており、詳細はあまり重要ではありませんが (私が思うに)、アプリをクラッシュさせる NullPointerException です。

私の実験から変更されたコードは次のとおりです。

同等のバージョン:

public class Card implements Serializable, Comparable<Card>{

追加された方法で:

public int compareTo(Card another) {
        if( another.getName() == null ) return -1;
        if( this.getName() == null ) return 1;
        return this.getName().compareTo(another.getName());
    }

通常版・オリジナル版:

public class Card implements Serializable/*, Comparable<Card>*/{

追加のメソッドなし。

それ以外の場合、クラスは同じです。getName() は文字列を返すことに注意してください。

次の実験を行いました。

  1. スマートフォンからアプリを完全にアンインストールします。
  2. コードに相当する変更を加えずにアプリをビルドし、Eclipse を介して携帯電話で実行します。(正常に動作します)。
  3. Comparable の変更を実装し、Eclipse を介して携帯電話で実行します。(正常に動作します)。

ここでは問題ありません。ここで、上記の各ビルドの署名付きバージョンをエクスポートしました。

  1. スマートフォンからアプリを完全にアンインストールします。
  2. 同等の変更なしでアプリの署名済みバージョンをエクスポートします。次を使用して電話にアップロードします: adb install com.myapp (正常に実行されます)。
  3. 同等の変更を加えた署名付きバージョンのアプリをエクスポートします。adb を使用してアップロードします。以前に保存されたアクセス時にクラッシュします (NullPointerException)。

そして、健全性チェックとして、次のことを行いました。

  1. 電話からアプリを完全にアンインストールします。
  2. 同等の変更を加えて、エクスポートされ、署名されたバージョンのアプリをインストールします。問題はありません。

手順 1. と 2. の間でアンインストールしない理由は、エンド ユーザーが更新間で自分のデータを保持することをシミュレートするためであることに注意してください (ここでの重要な機能)。また、上記の最終的なサニティ チェックにより、Serializeable クラスへの変更に伴う問題であることがかなり確実に感じられることに注意してください。

基本的な質問は次のとおりです。署名され、エクスポートされたアプリと、Eclipse 内から実行されるバージョンの違いは何ですか? Serializable クラスへの有効な変更がエクスポート後にアプリを壊す理由はありますか?

4

1 に答える 1

2

これは難読化によって引き起こされた問題のようです。Eclipse で実行するアプリも、別のキー/証明書を使用して署名されているため、実質的な違いはありません。ProGuard を使用している場合、「リリース」バージョンをエクスポートするとコードも難読化され、その過程で一部のクラスまたはメソッドが削除される可能性があります (ProGuard がそれらが使用されていないと判断した場合)。したがって、スタック トレースは重要であり、NPE が発生している正確な場所を特定する必要があります。次に、このクラス/メソッドを無視して再度テストするように ProGuard をセットアップします。

于 2011-09-04T04:42:43.367 に答える