1

自從Android引入了庫項目以來,我一直在將我的應用程序轉換爲庫,以便可以通過適當的調整來製作多個版本(例如,使用相同的自由和專業版本代碼庫,但改變了一些東西)。從Android庫調用非庫代碼

我最初有麻煩讓圖書館項目的代碼訪問我的子項目中的字段。換句話說,我的免費和專業版本每個都有一個包含少量常量的類,圖書館項目將用它來區分某些功能。

在子項目中,我擴展了庫的主要活動並添加了一個靜態初始化塊,它使用反射更改庫中字段的值。

public class MyMainActivityProVersion extends MyMainActivity { 

    public static final String TAG = Constants.APP_NAME + "/SubClass"; 

    static { 
     try { 
      ConstantsHelper.setConstants(Constants.class); 
     } catch (Exception e) { 
      Log.d(TAG, "--- Constants not initialised! ---"); 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 
} 

在這段代碼,ConstantsHelper是在圖書館,和我從我的子項目提供Constants.class。這會初始化庫項目中的常量。

我的方法很好,除了一個特定的用例。當應用程序在一段時間內沒有被使用並且被操作系統「停止」時,ConstantsHelper中的靜態字段將被遺忘。

常數應該由主要活動重置(如上所示),但主要活動甚至沒有啓動,因爲操作系統恢復了不同的活動。其結果是,常量的初始化被遺忘了,我不能重新初始化它們,因爲恢復的活動在圖書館(它不知道子項目)。

我該如何'告訴'庫中的其他活動來調用子項目中的代碼來恢復?或者,是否有辦法確保我的子項目中的某些代碼在每個簡歷上都被調用?

+0

我可能可以解釋類加載器中發生的事情,但我還沒有完全理解 - 您是指「圖書館中恢復的活動」是什麼意思?它是'MyMainActivityProVersion',正確的,它在你的應用程序中。常數被遺忘是什麼意思? –

+0

MyMainActivity繼續調用一些其他活動,在這種情況下它是ViewerActivity,它駐留在庫項目中。如果用戶在ViewerActivity上,然後按下「home」,應用程序最終會關閉,並且ConstantsHelper中的常量必須重新初始化。他們不重新初始化,因爲當用戶恢復應用程序時,恢復的活動是ViewerActivity,並且我上面的重要代碼沒有執行 – HXCaine

+0

因此,常量值不僅僅是ProVersionActivity?你知道應用程序類嗎?無論啓動的「子活動」如何,它都會創建一次。 – thaussma

回答

0

恐怕我從來沒有找到這個問題的好答案。我可能會繼續使用可怕的反射,並找出一些黑客的解決方法。

我覺得我應該回來,至少指出我沒有解決這個問題,爲了這個頁面的其他人的利益。

0

我認爲你是通過嘗試通過靜態成員在兩個活動間共享數據來「作弊」的。當他們在相同的或相關的類加載器中時,這恰好工作。在這裏我相信Android使用單獨的類加載器來執行單獨的活動,但是,子活動位於子類加載器中。所以ViewActivity恰好能夠看到父類加載器並查看父類的靜態。後來我相信父母會離開,所以當你下次訪問時,你的孩子在本地重新加載MyMainActivity,並且它沒有按照你的意願初始化。 (好吧,如果不是這樣的話,這是非常像這樣的解釋。)

我認爲還有一些更強大的選擇。您可以使用LicenseChecker API來決定您是否使用免費或付費版本,而不是依賴活動生命週期和類加載器的詳細信息。這可能會更好,因爲它可以保護您免受其他類型的未經授權的使用。

+0

您可能誤解了情況(並且我不'不要怪你,閱讀文字說明很難)。我不是在活動中共享靜態成員,而是通過圖書館中的常量類來共享這些靜態成員,並通過子項目的活動「填充」有用的信息。所有圖書館的活動都可以訪問它。但是,當應用程序被操作系統殺死時,常量類是「未初始化」的,我無法讓庫項目「查看」子項目及其中的代碼來填充這些項目常量。這是我的問題 – HXCaine

+0

我可能會誤解,但是你所描述的仍然聽起來像你依賴與類本身相關的東西,而不是對象或實例。一個類不能「uninitialize」 - 但是你肯定可以在一個新的類加載器中重新加載這個類,或者發現自己創建一個新的單例類或者什麼東西,這是我給出的原因。它仍然可能是一個紅鯡魚 - 將不得不看代碼 - 但希望澄清這個想法是否相關。 –

0

您可以使用Android資源解決此問題。 基本上,在庫項目的資源xml值文件中定義常量
E.g. 「lib項目」\ values \常量。XML

<resources xmlns:tools="http://schemas.android.com/tools"> 
    <bool name="const_free_version">false</bool> 
    <string name="const_a_constant">pippo</bool> 
</resources> 

然後,在你的子項目,你可以使用不同的資源XML值文件重新定義的lib項目值:
例如「子項目」 \值\ constants.xml

<resources xmlns:tools="http://schemas.android.com/tools"> 
    <bool name="const_free_version">true</bool> 
</resources> 

在你的lib項目代碼時,你指的R.bool.const_free_version你基於子項目常量XML的實際值。
請注意,您不必重新定義lib項目constants.xml中定義的每個值,但只需要在子項目中使用不同的值。