簡體   English   中英

Android令人頭疼的字符串:如何在應用程序中集中所有字符串?

[英]Android headache with Strings: How can I centralize all strings within my app?

我正在編寫一個Android應用程序,因此我照常將所有字符串都放在了strings.xml ,並根據Android官方文檔進行了說明。

到這里為止一切都很好,但是當我想在Java“標准”類中使用String時,問題就出現了。 也就是說,在Email.java說這個String:

public static final String EMAIL_NOT_VALID = "The email address provided is not valid.";

您可以說我可以將此String放在strings.xml並執行以下操作:

getResources().getString(R.string.invalid_email_message)

這種方法的問題是, 我將被迫將Android Context傳遞給應用程序中的每個Java對象,並涉及到測試時涉及的所有模擬問題。

因此,是否可以在不傳遞上下文的情況下執行此操作? 還是我需要兩個文件( strings.xmlxyz.java )使用單獨的字符串

我一直在找上幾個小時在StackOverFlow上解決這個問題的答案,但是沒有運氣)

提前致謝。

不要保存您的字符串,尤其是代碼類中的消息。 決不。 您不能將其翻譯成其他語言。 對所有內容都使用字符串資源,也許除了一些僅在調試器中看到的日志消息之外。

您可以創建一個類似Globals.java的類,並在其中放置一個

public static Context appContext;

然后在appStart(= MainActivity的“ onCreate”)上填充此靜態

Globals.appContext = getApplicationContext();

然后到處都有上下文。 只要確保您從后台回來,就可以在MainActivity的onResume事件中刷新上下文。

您會在整個Android API中看到帶有上下文的“問題”-SQLiteOpenHelper需要上下文... 一切都需要上下文。 這是Android游戲的一部分。

您可以嘗試將字符串放入assets文件夾中,需要在YourProject/app/src/main/assets內部的YourProject/app/src/main/assets中創建它,您可以創建一個名為“ localization”的新文件夾,並在此處存儲您的本地化文件(例如strings_en )完成所有這些操作后,將所有字符串存儲在JSON對象"{"key" : "value"} ,您需要創建一個類來管理所有語言。

public class LocalizationManager {

   private static LocalizationManager mInstance = null;
   public String currentLanguage = "";
   JSONObject currentLanguageObject = new JSONObject();
   private AssetManager assetManager = BaseApplication.getInstance().getAssets(); // BaseApplication is just a class that extends Application class

   private LocalizationManager() {
   }

   public static LocalizationManager getInstance() {
       if (mInstance == null) {
           mInstance = new LocalizationManager();
       }
       return mInstance;
   }

   private boolean assetExists(String path) {
       boolean bAssetOk = false;
       try {
           InputStream stream = assetManager.open(path);
           stream.close();
           bAssetOk = true;
       } catch (IOException e) {
           e.printStackTrace();
       }
       return bAssetOk;
   }

   public String getLocalizedString(String string) {
       String language = BaseApplication.getInstance().getLanguage();
       if (!currentLanguage.equalsIgnoreCase(language)) {
           if (assetExists("localization/strings_" + language)) {
               InputStream input;
               try {
                   input = assetManager.open("localization/strings_" + language);
                   int size = input.available();
                   byte[] buffer = new byte[size];
                   input.read(buffer);
                   input.close();
                   String responseString = new String(buffer);
                   Object json;
                   try {
                       json = new JSONTokener(responseString).nextValue();
                       if (json instanceof JSONObject) {
                           currentLanguageObject = (JSONObject) json;
                           currentLanguage = language;
                           return currentLanguageObject.optString(string, string);
                       }
                   } catch (JSONException e) {
                       return string;
                   }
               } catch (IOException e) {
                   return string;
               }
           }
       } else {
           return currentLanguageObject.optString(string, string);
       }
       return string;
   }
}

然后,在任何類中,您只需調用LocalizationManager.getInstance().getLocalizedString("Your string key") 使用這種方法,您將需要在應用程序中添加“更改語言”選項,將值存儲為en ,例如在首選項中,並且語言將動態更改。 這是我的做法:

public void setLanguage(String language) {
    mPreferences = getSharedPreferences(LANGUAGE_KEY_FOR_PREFS, MODE_PRIVATE);
    SharedPreferences.Editor editor = mPreferences.edit();
    editor.putString("Language", language);
    editor.apply();
    mListener.onLanguageChanged();
}


public String getLanguage() {
    mPreferences = getSharedPreferences(LANGUAGE_KEY_FOR_PREFS, MODE_PRIVATE);
    return mPreferences.getString("Language", "en");
}

您可以使用:

Resources.getSystem().getString(android.R.string.somecommonstuff)

...在應用程序中的任何地方,甚至在靜態常量聲明中也是如此。 不幸的是,它僅支持系統資源。

從堆棧中的線程之一溢出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM