2017-05-11 9 views
2

私はAndroidアプリを開発しています。私は自宅のMacBookと自宅のWindowsコンピュータから離れています。私は両方のマシンで同じJDKバージョン(1.8.0_131)を持っており、ここに示すような正しいJDKパスを設定しています:How to set the JDK in Android Studio2台のコンピュータでAndroidアプリケーションをテストすると非常に異なる結果が発生する

どちらのマシンでもClass.getDeclaredFields()メソッドを呼び出すと、私は非常に異なる結果になります。私のMacでは、このメソッドは、公共のフィールドだけを見ているようだが、Java-Docのように振る舞う。私のWindowsコンピュータでテストするとき、メソッドはすべてのフィールドを継承したものを返します。これは明示的にJava-Docがメソッドがしないと言っているものです。私はClass.getDeclaredFields()が一貫している必要があります。なぜなら、JSONファイルをGsonでビルドし、プログラムの別の場所にディスクに格納するためです。

さまざまなAndroid Runtimeがあり、プログラムの動作が異なると思われますが、その情報をどこで見つけるか、この問題を修正して展開時に一貫して動作するようにはわかりません。

どちらのマシンでも、Android API 25(Android 7.1.1 Nougat)とビルドツール25.0.2でNexus 5X仮想デバイスを使用しています。

public abstract class Article { 

    protected Context context; 
    protected int id;//start at 0 and go up. 
    private Texture texture; 
    private Temperature idealTemp; 
    private Formality formality; 
    private String name; 
    private int color; //expressed as hex RGB 
    private Bitmap image; 
    JsonObject articleData; 

    ... 

    @Override 
    public String toString() { 
    //TODO: for efficiency, this should be StringBuilder 
    String temp = "id: " + id + ", texture: " + texture + ", idealTemp: " + idealTemp 
      + ", formality: " + formality + ", name: " + name + ", color: #" + color; 

     Field[] fields = this.getClass().getDeclaredFields(); 
     for (Field f : fields) { 
      try { 
       temp = temp.concat(", " + f.getName() + ": " + f.get(this).toString()); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
       continue; 
      } 
     } 

     return temp; 
    } 
}//end class 

条を継承するクラスがトップで次のようになります:メソッドArticle.toStringを使用しています

public abstract class Top extends Article { 

    public Top(Context con, Texture tex, Temperature temp, Formality form, String n, int col, Bitmap img) { 
     super(con, tex, temp, form, n, col, img); 
    } 

} 

そして最後に非抽象クラスを

は、ここに私の特定の実装です()はシャツです:

public class Shirt extends Top { 

    //If this is not public, it is not seen by getDeclaredFields() 
    //seems to be a bug in the Android Runtime on my Mac? 
    public boolean longSleeves; 

    public Shirt(Context con, Texture tex, Temperature temp, Formality form, 
      String n, int col, Bitmap img, boolean longSleeve) { 
     super(con, tex, temp, form, n, col, img); 
     longSleeves = longSleeve; 
    } 
} 

更新日:私が最初に投稿したコード代わりに

getDeclaredFields() 

getFields() 

をsedはこれが変更されたと私は、Android Studioのショーで私のデバッガのものを両方表示するには画像が含まれます: マック:enter image description here

Windowsの場合:enter image description here

+0

どこでgetDeclaredFields()を呼び出していますか?あなたの質問に正しいコードを含めましたか? – user695022

+0

getDeclaredFields()を使用するようにコードを更新しましたが、同様の問題があります。上記の質問の更新を参照してください。 –

答えて

1

MacとPCで異なるコードがあると思います。あなたはgetDeclaredFields()を呼び出すと言いますが、投稿したコードはgetFields()です。あなたが投稿したコードがあなたのPCからのものであれば、それが継承された公開フィールドを見ている理由です。

プライベートフィールドにアクセスできないようにアクセスしようとしているため、プライベートフィールドが表示されません。例外がスローされ、ログと無視が行われます。ログを確認すると、非公開フィールドごとに例外が表示されます。文字列にフィールド名を追加するか、getを呼び出す前に各フィールドのsetAccessible(true)に電話してみてください。

UPDATE:

changeserialVersionUIDフィールドがどこから来ている私は知りません。私は、自動的にそれらを含めるためにIDEまたはコンパイラ設定があると思う。静的なフィールドなので、それらをフィルタリングすることができます。とにかくこれをやりたいと思うでしょう。

for (Field f : getClass().getDeclaredFields()) { 
    if (Modifier.isStatic(f.getModifiers()) continue; 
    if (!f.isAccessible()) { 
     f.setAccessible(true); 
    } 
    Object value = f.get(this); 
    temp += ", " + f.getName() + ": " + String.valueOf(value); 
} 
+0

私はあなたに同意するだろうが、なぜ同じコードを持っている私のWindows環境で何か違うことが起こっているのか分からない。 Windowsコードは、Macからプッシュした後、私のレポからまっすぐに引き出されました。私のMacのコードは変更されていないとgitは、すべてがリモートブランチで最新のものだと言います。 –

+0

あなたの助けをありがとう、このソリューションはかなり良いです。ある日、私のIDEがこのようにプログラムをコンパイルしているかもしれない理由がわかります。 –

+1

増分変更フィールドについて、[この質問](https://stackoverflow.com/questions/36235608/public-static-runtime-incremental-change-android)が見つかりました。デバッグ用にしか存在しないようです。 – user695022

1

これをコメントとして追加しますが、評判が十分ではありません。
アドバイスの一部:

1.リフレクションを使用しないでください。時間の99%は、悪いデザインの回避策に過ぎません。リファクタリングについて考えてみましょう。

2.抽象クラスをまったく使用しないでください。代わりにインターフェイスを使用してください。

+0

リフレクションの使用を避けるように設計された実装がありますが、この実装を選択したのは、複数のメソッドの関連するコードをすべてArticleクラスに集中させるためです。代わりに他のデザインを使う方がいいかもしれません。 –

関連する問題