14

文字列整数に変換する静的ハッシュ テーブルを作成したいと考えています。ここでの注意点は、 XML ファイルのいくつかのリストでリソースとして定義した文字列を使用したいということです。

リソースIDのみを使用して、これを書くことができます:

public class MyActivity extends Activity {

private static Map<Integer, Integer> views = new HashMap<Integer, Integer>();
static {
    views.put(R.string.full_text, MessageTable.VIEW_FULL);
    views.put(R.string.only_text, MessageTable.VIEW_MSG);
    views.put(R.string.tag_text, MessageTable.VIEW_TAGMSG);
}

エラーは発生しませんが、実際に行う必要があるのは次のようなものです。

public class MyActivity extends Activity {

private static Map<String, Integer> views = new HashMap<String, Integer>();
static {
    views.put(getResources().getString(R.string.full_text), MessageTable.VIEW_FULL);
    views.put(getResources().getString(R.string.only_text), MessageTable.VIEW_MSG);
    views.put(getResources().getString(R.string.tag_text), MessageTable.VIEW_TAGMSG);
}

これにより、Eclipseで次のエラーが発生します。

Cannot make a static reference to the non-static method getResources() from the type ContextWrapper

メッセージは理にかなっていますが、理にかなっていないのは、静的ブロックからリソースに到達できないことです。静的変数はリソースを利用するためにカスタム作成されたと思われるでしょう。
オブジェクト コンストラクター中にハッシュ テーブルにデータを入力できると思いますが、これは間違った場所で行うことを意味します。

4

5 に答える 5

12

getResources()( ~ の略MyActivity.this.getResources()) には、その時点で初期化されていないコンテキスト オブジェクトが必要です。コンテキストはヒットした後にしか利用onCreateできないため、 の構築時にそれを行うことさえできませんMyActivity

その理由は、MyActivityクラスをインスタンス化するアクティビティ マネージャーは、xml から抽出する必要があるリソースを知る前に、構成 (向き、画面サイズ、言語など) を決定する必要があるためです。-> リソースは静的ではなく、静的コンテキストからアクセスできません。

onCreateしたがって、これらの操作を後で行う方法はないと思います。

編集:確かに静的 HashMap (または static Context)を更新するonCreateことはできますが、構成が異なる可能性がある同じアクティビティの複数のインスタンスを持つことができるため、お勧めしません。また、静的なデータを格納することは、メモリ リークContextを作成する優れた方法です。

于 2012-04-17T16:55:14.073 に答える
8
public Static Resources mResources;
public MyApplication extends Application
{
     @Override
     public void onCreate()
     {
           mResources = getResources();
     }

}

リソースへの静的参照を取得したら、アプリケーション全体のどこからでも参照できます。ただし、これが一時的なリークを引き起こすかどうかはわかりません。

于 2015-03-07T10:32:10.793 に答える
1

できることの 1 つは、Applicationクラスを作成して AndroidManifest.xml に登録することです。次に、onCreate メソッドをオーバーライドし、Application クラスを静的参照として設定してから、Activity クラスに触れて静的初期化子を実行します。Applicationクラスは、apk がメモリに読み込まれるときに実行されるため、常に の前に実行されますActivity

これにはいくつかの重大な欠点があります。私が考える最も明白なものは、システム言語が変更され、これらのリソースに翻訳が追加された場合です。アプリケーションはデフォルトの言語を使用するため、アプリケーションが起動されたときの言語が何であれ、一貫性のない文字列が作成されます。文字列リソースは Android のリソース管理システムの影響を受けるため、向き、システム言語、画面サイズなどの変更は、これらの値に影響を与える可能性があります。これが、次の場合にアクティビティがリセットされる理由です。

要するに、このジョブには一定の文字列のキーと値のペアを使用する方がよいということです。翻訳をより適切に処理できるように、文字列リソースを使用する必要がある場合。アクティビティが開始されるたびにそれらをロードします。そうしないと、メモリ リークや一貫性のない文字列変換が発生する危険があります。

public MyApplication extends Application {

  public static Context GlobalContext = null;

  @Override
  protected void onCreate() {
    MyApplication.GlobalContext = this;

    // Touch the activity class.
    MyActivity activity = new MyActivity();
    // Throw it away by not using it.

    // invalidate handle to prevent GC leaks.
    GlobalContext = null;
  }
}

public class MyActivity extends Activity {
  private static Map<String, Integer> views = new HashMap<String, Integer>();

  static {
    Context context = MyApplication.GlobalContext;
    Resources res = context.getResources();
    views.put(res.getString(R.string.full_text), MessageTable.VIEW_FULL);
    views.put(res.getString(R.string.only_text), MessageTable.VIEW_MSG);
    views.put(res.getString(R.string.tag_text), MessageTable.VIEW_TAGMSG);
  }
}
于 2012-04-17T17:09:39.377 に答える
0

ApplicationContext への静的参照を常に保持できます。考えられる方法は次のとおりです: Android で「コンテキスト」を取得する静的な方法は?

于 2012-04-17T16:57:52.837 に答える
0

最善の方法はわかりませんが、たとえば、私のアプリには、現在のアクティビティとコンテキストを保持するシングルトン (GuiaUtil と呼ばれる) があります。

private static Map<String, Integer> views = new HashMap<String, Integer>();
static {
views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.full_text), MessageTable.VIEW_FULL);
views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.only_text), MessageTable.VIEW_MSG);
views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.tag_text), MessageTable.VIEW_TAGMSG);
}
于 2012-04-17T16:58:01.340 に答える