2013-12-14 41 views
20

Builder代碼我使用Retrofit,並在每個任務我必須做這樣的事情:有沒有辦法重新用於改造

public class MyTask extends AsyncTask<String, String, String> { 

    private void someMethod() { 
     final RestAdapter restAdapter = new RestAdapter.Builder() 
      .setServer("http://10.0.2.2:8080") 
      .build(); 
     final MyTaskService apiManager = restAdapter.create(MyTaskService.class); 
    } 

    // ... 

} 

是什麼使這個代碼乾的好辦法?

+0

你從哪兒弄來'RestAdapter'?我可能知道嗎? – Geros

+0

DRY是什麼意思? – Husyn

+1

你可以使用一些繼承概念 –

回答

5

第一你所有常見的行爲,聲明你的父類

public abstract class MyAbstractTask extends AsyncTask<String, String, String> { 

protected void someMethod() { //note that i change private to protected 
    final RestAdapter restAdapter = new RestAdapter.Builder().setServer("http://10.0.2.2:8080").build(); 
    final MyTaskService apiManager = restAdapter.create(MyTaskService.class); 
} 

} 

那麼,你與每一個任務

public class MyTask extends MyAbstractTask { 

//your someMethod() is available from everywhere in your class 

} 

public class MyOtherTask extends MyAbstractTask { 

//your someMethod() is available from everywhere in your class 

} 

擴展它,但我不知道你在哪裏使用restAdapter和apiManager ,並且如果實際上每個任務需要創建一次,則可能可以在這些任務之外創建它。

如果你在外面創建它們,然後你需要在你的任務中使用某些東西,那麼記住Dependency_injection模式也是很好的做法。


此外,應避免硬編碼值在你的類,像http://10.0.2.2:8080

你應該至少使用一個final static final String server= "http://10.0.2.2:8080",然後使用,或更好,使用一個設置或構造在最內部類,並從活動或主控制器中設置值。

42

RestAdapter和生成的服務實例(在這種情況下爲MyTaskService)都是非常昂貴的對象,應該用作單例。

這意味着您應該只呼叫restAdapter.create一次,並在您每次需要與之交互時重複使用相同的MyTaskService實例。

我不能強調這一點。

您可以使用常規單例模式,以確保只有這些對象的單個實例在任何地方都可以使用。依賴注入框架也可以用來管理這些實例,但如果你還沒有使用它,會有點矯枉過正。

+1

感謝您的迴應。我基於使用'newProxyInstance'創建請求實例的改造中使用Proxy類的創建調用。我在一臺設備上運行(Nexus 5運行4.4),該接口定義了1到4種不同複雜度的服務方法。第一次耗時4-5毫秒,0.3-0秒。在同一運行中,每一個隨後的時間5毫秒。也許我不明白這一點,但是有沒有理由認爲這很貴? Android也是在第一次緩存創建?只是試圖弄清楚一點,這就是所有 – Rickster

+1

它的運行速度並不昂貴,而是在內存方面。每個RestAdapter佔用大量的內存,這就是爲什麼在這裏需要一個單例,因爲一次只能在內存中有一個副本。圖像你做10,更不用說100的請求,每個請求都有自己的RestAdapter。垃圾收集器無法快速清理它們,並且可以很容易地從內存中解決這個問題。 Android沒有緩存這個,但你可以很容易地用[Singletons](http://www.javaworld.com/article/2073352/core-java/simply-singleton.html)來完成。 – yiati

+0

@JakeWharton這仍然是這樣嗎?我剛剛創建了100個RestAdapter,但沒有顯着增加內存。 – Eugene

44

正如Jake所說,您應該使用singleton pattern以確保始終使用相同的實例。

下面是一個例子:

public class ApiManager { 

    public interface GitHubService { 

     @GET("https://stackoverflow.com/users/{user}/repos") 
     List<Repo> listRepos(@Path("user") String user); 

    } 

    private static final String API_URL = "https://api.github.com"; 

    private static final RestAdapter REST_ADAPTER = new RestAdapter.Builder() 
     .setEndpoint(API_URL) 
     .setLogLevel(LogLevel.FULL) 
     .build(); 

    private static final GitHubService GIT_HUB_SERVICE = REST_ADAPTER.create(GitHubService.class); 

    public static GitHubService getService() { 
     return GIT_HUB_SERVICE; 
    } 
} 

您可以使用該服務在這個例子中,像這樣:

ApiManager.getService().listRepos(...); 
+1

@Gautham爲每個請求我必須使用不同的converter.how使用單身? – Asthme

+0

@Asthme爲什麼你想要爲每個請求使用不同的addConverterFactory? – Lobato

相關問題