2011-03-03 61 views
1

假設我有我的Android應用程序的源代碼打包這樣:獲取一個基類的子類的實例

src/ 
    my/ 
     app/ 
     Module.java 
     ModuleManager.java 
     module/ 
      ModuleA.java 
      ModuleB.java 

其中Module是:

public abstract class Module { 
    public abstract void run(); 
} 

ModuleAModuleB延伸Module

public class ModuleA extends Module { 
    @Override 
    public void run() { /* do something */ } 
} 

ModuleManager有一定的輔助方法,其中一個檢索所有Module S:

public class ModuleManager { 

    private final static List<Module> modules; 
    static { 
     List<Module> tmp= new ArrayList<Module>(); 
     tmp.add(new ModuleA()); 
     tmp.add(new ModuleB()); 
     modules= Collections.unmodifiableList(tmp); 
    } 

    public static List<Module> getModules(){ 
     return modules; 
    } 
} 

正如你可以看到我在ModuleManager手工填寫的模塊列表。相反,我希望它是自動填充Module的所有子類型的實例模塊包。

我想在幾個方面基於反射的解決方案like this,其涉及使用ClassLoader::getResource(String path)檢索模塊包內的每個.class文件,但它總是會返回一個空的枚舉。我瞭解到這是由於Dalvik的VM和Java SE的不同之處,以及它在類中的.class文件的優化打包.dex。然後我嘗試從/data/app/DexClassLoaderPathClassLoader導入應用程序的apk,並且再次嘗試了他們的getResource()方法。無論如何,我認爲這不是正確的方向,可能這個東西在Java中已經是黑客/有缺陷的,而且在Android中會更多。

你能告訴我一種方法嗎?

非常感謝。

回答

2

一個在構建腳本來做到這一點的方式,後編譯之前,但在dex被調用來創建classes.dex之前,運行一個小腳本以獲取modules文件夾中的類名稱,並將其寫入以聲明要從中讀取的application.properties文件(或resources.xml中的strings.xml)。

這樣做的缺點是它不是您要求的純java方法,其優點是它可以用於2個或10個以上的子類。希望這可以幫助。

+0

謝謝,這是一個好主意! – 2011-03-04 09:52:47

1

如果你添加一個XML或屬性與模塊類和你動態地從它創造......它可能是這樣的

<modules> 
    <module> 
    my.app.module.ModuleA 
    </module> 
    <module> 
    my.app.module.ModuleB 
    </module> 
</modules> 
+0

謝謝你提到Java的'Property',我從來沒有搞砸過它,但它似乎是一個有趣的機制。 – 2011-03-04 09:56:00

1

另一種解決方案可能是利用類名稱的命名約定,並用Class.forName(className)逐一檢索它們。在我所做的例子中,如果我知道所有模塊按順序命名爲ModuleAModuleBModuleC等,我可以從ModuleA開始檢索所有模塊,並繼續到Class.forName("ModuleX")失敗。如果允許差距但模塊數量有限(並且非常低),則可以對整個範圍進行詳盡的搜索。

當然,這可以應用在極少數情況下,並以類的名稱可讀性爲代價。