2014-05-09 121 views
1

好吧,我有一個問題,試圖混合框架。 因此,我有一個@SharedPref註釋類,它應該從Android Annotations生成一個共享首選項管理器。該類看起來有點像這樣:匕首沒有注入Android註解類

DownloadPrefs.java

@SharedPref(value= SharedPref.Scope.UNIQUE) 
public interface DownloadPrefs { 

    @DefaultBoolean(false) 
    boolean hasEnabledDownload(); 

    @DefaultBoolean(false) 
    boolean showedDownloadDialog(); 

    @DefaultLong(0) 
    long downloadRefreshedOn(); 
} 

現在,我想結果類(這將是DownloadPrefs_)注入到一個片段利用它。該片段已添加新模塊工作注入,所以我只打算在這裏寫我說什麼:

Fragment.java

@Inject DownloadPrefs_ downloadPrefs; 

現在,由於實際DownloadPrefs_類是在運行時產生的,它最有意義的是爲它創建一個@Provides註釋,因爲我不能將構造函數標記爲注入。 DownloadPrefs_也沒有一個無參數的構造函數。我使用該模塊然後接收新@Provides

DownloaderModule.java

@Provides //@Singleton // Does not work with/out @Singleton 
DownloadPrefs_ provideDownloadPrefs() { 
    return new DownloadPrefs_(MinimalBible.getApplication()); 
} 

要技術它,是可以獲得由Android批註產生的DownloadPrefs_構造函數需要傳遞給它一個背景下,我也能猜到應用程序上下文將是合適的。否則,我不知道我怎樣才能訪問Activity上下文。或者是否真的會破壞ObjectGraph

然而,當我去運行實際注入,我得到以下信息:

Caused by: java.lang.IllegalStateException: Errors creating object graph: 
    org.bspeice.minimalbible.activities.downloader.DownloadPrefs_ has no injectable members. Do you want to add an injectable constructor? required by class org.bspeice.minimalbible.activities.downloader.BookListFragment 

上發生了什麼事情的任何線索?似乎並沒有在其他SO問題上詢問「無注射成員」的問題回答了我的案例。在添加上面的代碼之前,我有一個工作應用程序。

UPDATE:做一些仔細檢查後,我碰到下面的怪異的行爲。如果我將預構建的Android Annotations類複製出來,重新命名並注入,那麼一切正常。此外,我可以驗證原始的內置Android註釋類(DownloadPrefs_.java)確實存在於.dex中,因此Dagger應該沒有理由無法找到它。一切都在進行調試構建,所以我無法想象ProGuard會搞亂任何東西。

在這一點上,我將創建一個最小的項目來演示錯誤,並向Dagger提出問題。與此同時,只需要重寫Prefs類,直到我可以把它整理出來。

UPDATE 2014年5月12日

下面是負責噴射模塊時:

MinimalBibleModules.java

@Module(
    injects = { 
     MinimalBible.class 
    }, 
    includes = { 
     ActivityModules.class 
    } 
) 
public class MinimalBibleModules { 
} 

ActivityModules。java的

@Module(
    includes = { 
     ActivityDownloaderModule.class 
    } 
) 
public class ActivityModules { 
} 

ActivityDownloaderModule.java

@Module(
     injects = { 
      BookListFragment.class, 
      DownloadManager.class, 
      BookRefreshTask.class 
     } 
) 
public class ActivityDownloaderModule { 

    @Provides @Singleton 
    DownloadManager provideDownloadManager() { 
     return new DownloadManager(); 
    } 

    @Provides 
    EventBus provideBus() { 
     return new EventBus(); 
    } 


    @Provides //@Singleton 
    DownloadPrefs_ provideDownloadPrefs() { 
     return new DownloadPrefs_(MinimalBible.getApplication()); 
    } 
} 

此外,圖形創建方式:

MinimalBible.java

public class MinimalBible extends Application { 

    private ObjectGraph graph; 

    private static MinimalBible instance; 

    public MinimalBible() { 
     instance = this;   
    } 

    @Override 
    public void onCreate() { 
     graph = ObjectGraph.create(new MinimalBibleModules()); 
     graph.inject(this); 
    } 
+0

創建Github的問題[#410](https://github.com/square/dagger/issues/410)用匕首,所有進一步的討論可能將在那裏舉行。 –

+0

我通常會責怪proguard的 - 尤其是確保它不殺生的事情 - 但如果你說的時候沒有proguard的這種情況,我是那麼迷茫。 DownloaderModule中的「@ Provide」行是否被編譯?如果是這樣,那麼proguard就不要把它取出來。您是否將DownloaderModule包含在您配置圖形的主模塊中?可以請你在'@ Module'添加註解你的主要模塊的外殼,你創建一個圖形的線,和屬性設置?這很重要,看看你是否把一切都搞好了。 –

+0

該項目使用AndroidAnnotation並生成類DownloadPrefs_沒有任何內部聲明注入。 – Mikooos

回答

1

的這裏有兩個部分。首先,你如何訪問Context。你可以像現在這樣做靜態事物,儘管這不是可取的。一般來說,你應該攜帶的背景下,這樣的狀態的模塊配置圖:

@Module 
class ApplicationModule { 
    private final Application application; 

    public ApplicationModule(Application app) { 
    this.application = app; 
    } 

    // you can mark this singleton, but it's minor overhead 
    // and the fact that you have a single instance stored 
    // means it's semantically equivalent. But for clarity 
    // it's sometimes good to make the point. 
    @Provides 
    @Singleton 
    Application application() { 
    return application; 
    } 

    // optionally: bind it as a Context with a qualifier. 
    // note: never bind Context without a qualifier annotation 
    // as Activity and Application are both Context subtypes. 
    @Provides 
    @Singleton 
    @PerApplication 
    Context appContext(Application app) { 

    // Doing this instead of returning this.application is 
    // semantically equivalent but links @PerApplication Context 
    // to Application, so in graph analysis and error reporting 
    // the link is clearer. That's a personal choice. 
    return app; 
    } 
} 

無論如何,你那麼當你創建圖形:

Application appInstance = ...; 
ObjectGraph appGraph = ObjectGraph.create(
    MyAppModule.class, 
    new ApplicationModule(appInstance)); 

的應用,然後接種放入圖中,並可以由其他類型聲明爲依賴。