Вопрос по java, retrofit, android – Есть ли способ повторно использовать код разработчика для модернизации

20

я используюмодифицировать и в каждой задаче я должен сделать что-то вроде этого:

public class MyTask extends AsyncTask {

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

    // ...

}

Каков хороший способ сделать этот код сухим?

@Husyn, DRY означает «Дон»Повторите себя Carlos Robles
Что вы подразумеваете под СУХОЙ? Husyn
Где ты досталRestAdapter? Могу ли я знать? Geros
Вы могли бы просто использовать некоторые концепции наследования Rajesh Batth

Ваш Ответ

3   ответа
42

ОбаRestAdapter и сгенерированный экземпляр ваших услуг (MyTaskService в данном случае) являются чрезвычайно дорогими объектами и должны использоваться как синглтоны.

Это означает, что вы должны только звонитьrestAdapter.create один раз и повторно использовать тот же экземплярMyTaskService каждый раз, когда вам нужно взаимодействовать с.

Я не могу подчеркнуть это достаточно.

Вы можете использовать обычный одноэлементный шаблон, чтобы гарантировать, что существует только один экземпляр этих объектов, который вы используете везде. Инфраструктура внедрения зависимостей также может быть использована для управления этими экземплярами, но будет немного излишней, если вы ее еще не используете.

@ jake-wharton Это все еще действует для Retrofit 2? jbxbergdev
@jakewharton есть место, в котором я использую конвертер, но я не могу его назвать, так что я должен назвать explicilty call null, где я не использую? Asthme
@ JakeWharton Это все еще так? Я только что создал 100 RestAdapters без значительного увеличения памяти. Eugene
@ Евгений Да, это таквсе еще дорого. Вы можете не заметить 100 из них. Но если вы сравните эти объекты с каким-то повседневным выбрасываемым объектом, вы обнаружите, чтоболее дорогой в несколько сотен миллионов раз. Класс также был предназначен для повторного использования. Это's потокобезопасен, делает ленивую загрузку и кэширование и большая работа были направлены на оптимизацию случая повторного использования. Это'Это как покупать новые носки каждый день вместо того, чтобы стирать их. Вы можете сойти с рук, но это просто нене имеет смысла. zapl
5

сначала вы объявляете свой родительский класс со всем обычным поведением

public abstract class MyAbstractTask extends AsyncTask {

 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, и нужно ли создавать их один раз для каждой задачи, поскольку, вероятно, вы можете создать их вне этих задач.

Если вы создаете их снаружи, а затем вам нужно что-то использовать внутри своей задачи, также хорошо иметь в видуВнедрение зависимости шаблон.

Кроме того, вы должны избегать жесткого кодирования значений в ваших классах, таких какhttp://10.0.2.2:8080

Вы должны использовать хотя быfinal static final String server= "http://10.0.2.2:8080" и затем используйте это, или, лучше, используйте установщик или конструктор в самом внутреннем классе и установите значения из действия или основного контроллера.

44

Как сказал Джейк, вы должны использоватьсинглтон чтобы гарантировать, что всегда используется один и тот же экземпляр.

Вот'Вот пример:

public class ApiManager {

    public interface GitHubService {

        @GET("/users/{user}/repos")
        List 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(...);
@Asthme Почему вы хотите использовать разные addConverterFactory для каждого запроса? Rafael
@ Gautham для каждого запроса я должен использовать другой конвертер. Как использовать в качестве синглтона? Asthme

Похожие вопросы