2016-11-14 58 views
0

我有一個屬性文件存儲在資產文件夾的Android項目。我需要在每次需要值時避免該文件的I/O讀取,以便第一次加載文件並將其保存在靜態字段中。請記住,這是一款在嵌入式平板電腦上「始終運行」的應用程序,因此基本上沒有生命週期。這是我對本作的實現:在內存中的Android緩存屬性文件,以避免I/O

Properties.java:

private static java.util.Properties properties; 
private static Context mContext; 

public static void init(Context context) { 
    mContext = context.getApplicationContext(); 
    if(properties == null){ 
     AssetManager assetManager = context.getAssets(); 
     InputStreamReader reader = null; 
     try { 
      reader = new InputStreamReader(assetManager.open("path_to_prop_file"), "UTF-8"); 
      properties = new java.util.Properties(); 
      properties.load(reader); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       reader.close(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

public static String get(String entry){ 
    try { 
     return properties.getProperty(entry); 
    } catch (Exception e){ 
     init(mContext); 
     return properties.getProperty(entry); 
    } 
} 

然後我把它從活動:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Properties.init(getApplicationContext()); 
    String property = Properties.get("prop_key"); 
} 

我是緩存也語境的情況下,屬性文件需要被重新加載。我可以將上下文作爲參數傳遞給「Get」方法,但是我需要在應用程序中隨處讀取屬性,並且我不想通過所有類傳遞上下文。 我想知道如果這個實現是好的,並且在我的情況下關於上下文的泄漏是危險的。 任何建議被理解

EDIT 1:最後塊中追加關閉讀者所建議

+0

考慮關閉你的閱讀器在finally塊 –

+0

@NicolasFilotto當然我會感謝 – Nem3sis

回答

0

如果有關上下文泄漏發生在我的情況下

危險在泄漏方面, Application是全球單身人士。它是預泄漏的;你不能進一步泄漏它。您的Properties泄露,但這是設計。

我想知道如果這個實現是確定

你還沒有解決線程。在主應用程序線程上擁有這種I/O會導致丟幀和UI結果。而且,一旦開始進入線程,您的實現將變得更加複雜以處理競爭條件(例如,代碼在讀取屬性的線程完成執行之前想要使用屬性)。

我會重溫打包屬性文件的想法。例如,你可以:

  • 手工編寫包含這些屬性

  • 位的代碼添加到您的build.gradle文件,這些屬性轉換成在BuildConfig類字段的Java類,使用buildConfigField

  • 寫小代碼生成搖籃插件,你的屬性轉換成Java類(this book sample of mine這是否爲一個簡單的JSON文件)

+0

感謝@CommonsWare的回覆!如果我明白了,對java.util.Properties.getProperty(String)方法的每次調用都是讀入屬性文件的I/O?我認爲這只是InputStream執行一次I/O操作。我還會尋找Gradle解決方案來將prop轉換成java類 – Nem3sis

+0

@ Nem3sis:「我認爲這只是InputStream的I/O一次」 - 正確。我的假設是你在主應用程序線程上使用你的get()方法。如果這總是會在後臺線程上調用,那麼你不會用'init()'I/O阻塞主應用程序線程,那麼我的線程問題就會消失。 – CommonsWare

+0

是的,我在主線程上使用'get()'。我會在丟幀的情況下進行分析,並考慮如果情況在背景中移動。謝謝 – Nem3sis