RoboGuicewell-known DI framework for Android5/7/20111Android May Days 2011
Dependency InjectionУстранение зависимостей в кодеЗамена паттерна new()Избавление от рутины создания фабрик, заводов и цеховВозможность использования нескольких конфигурацийОграничение кол-ва инстанций классаУпрощение тестирования5/7/2011Android May Days2
RoboGuicehttp://code.google.com/p/roboguice/Первым делом, это DI фрэймворк, который также позволяет:@InjectView()@InjectResource()@InjectPreference()@Inject System Services@ObservesEvents5/7/2011I’m footer and nobody reads me3
Injecting RoboGuiceСкачатьRoboGuice 1.1.1 и guice-2.0-no_aop.jar и подключить их к проекту. Или есть прекрасная возможность начать пользоваться Maven’ом     (чего я еще не сделал)Добавить в проект класс наследник RoboApplication и прописать его в AndroidManifest.xlmв тэге application значением параметра android:name (“.MyRoboApplication”)5/7/2011Damn footer live4
Application Code Sample5/7/2011publicclassDiscoBoxApplicationextendsRoboApplication {@OverrideprotectedvoidaddApplicationModules(List<Module> modules) {modules.add(newNetSocketModule());modules.add(newDiscoBoxModule());super.addApplicationModules(modules);    }}I’m a poop-poor footer, no one likes me5
ModulesПроисходит настройка bind-ингов классов на конкретные объектыСтатическая инициализация5/7/2011I could be a header6bind(Client.class).to(SocketClient.class);@Providespublic Client provideClient() {        Client c = newSocketClient();requestInjection(c);return c;}requestStaticInjection(ClientServiceAPI.class);
Module Sample5/7/2011footer sample7publicclassNetSocketModuleextendsAbstractModule {publicstaticfinal String SERVER_BROADCAST_IN_PORT = "SERVER_BROADCAST_IN_PORT";publicstaticfinal String SERVER_BROADCAST_OUT_PORT = "BROADCAST_OUT_PORT";publicstaticfinal String SO_TIMEOUT = "SO_TIMEOUT";privatestaticfinalintSERVER_BROADCAST_IN_PORT_VALUE = 2012;privatestaticfinalintSERVER_BROADCAST_OUT_PORT_VALUE = 2013;privatestaticfinalintSO_TIMEOUT_VALUE = 20 * 1000;@Overrideprotectedvoid configure() {        bind(ProtocolProcessor.class).to(DefaultProtocolProcessor.class);        bind(Connection.class).to(DefaultConnection.class);        bind(Client.class).to(SocketClient.class);        bind(Server.class).to(SocketServer.class).in(Scopes.SINGLETON);        bind(ServerFinder.class).to(SocketServerFinder.class);                bind(Integer.class).annotatedWith(Names.named(SO_TIMEOUT))            .toInstance(SO_TIMEOUT_VALUE);        bind(Integer.class).annotatedWith(Names.named(SERVER_BROADCAST_IN_PORT))            .toInstance(SERVER_BROADCAST_IN_PORT_VALUE);        bind(Integer.class).annotatedWith(Names.named(SERVER_BROADCAST_OUT_PORT))            .toInstance(SERVER_BROADCAST_OUT_PORT_VALUE);    }}
InjectingС помощью @InjectC помощью Injector5/7/2011blah-blah-blah8   @Injectprotected Injector injector;@InjectpublicSocketServer(@Named(NetSocketModule.SERVER_PORT) intport) {        ...}@InjectpublicvoidsetProtocolProcessor(ProtocolProcessor processor) {this.processor = processor;}Connection connection = injector.getInstance(Connection.class);
Lazy InjectionИспользование интерфейса Provider<T>5/7/2011and lazy footer9@Injectpublic Provider<Server> serverProvider;publicvoidmethodRequersServer() {    Server servet = serverProvider.get();...}
ScopesМожно пометить класс аннотацией @Singleton, для ограничения кол-ва инстанций тяжелого ресурсоемкого класса5/7/2011scopes looks like footer friends10@SingletonpublicclassSocketServerimplements Server {...}
Constructors with paramsИспользование аннотаций и специальных биндингов5/7/2011what footers are good for?11@InjectpublicSocketServer(@Named(NetSocketModule.SERVER_PORT) int port, @Named(NetSocketModule.SERVER_BROADCAST_ADDRESS) String broadcastAddress,@Named(NetSocketModule.SERVER_BROADCAST_IN_PORT) intbroadcastInPort,@Named(NetSocketModule.SERVER_BROADCAST_OUT_PORT) intbroadcastOutPort) {}@Overrideprotectedvoid configure() {   ...bind(Integer.class).annotatedWith(Names.named(SERVER_BROADCAST_IN_PORT))            .toInstance(SERVER_BROADCAST_IN_PORT_VALUE);bind(Integer.class).annotatedWith(Names.named(SERVER_BROADCAST_OUT_PORT))            .toInstance(SERVER_BROADCAST_OUT_PORT_VALUE);bind(String.class).annotatedWith(Names.named(SERVER_BROADCAST_ADDRESS))            .toInstance(SERVER_BROADCAST_ADDRESS_VALUE);}
Constructors with paramsИспользование @Provides в модуле5/7/2011footer is watching you12@Provides Server provideServer() {        Server server = newSocketServer(2011, "224.0.0.0", 2013, 2014);requestInjection(server);return server;    }
EventsИспользовать уже готовые событий или написать свои5/7/2011footer, simple as is13publicvoidperformShutDown(@ObservesOnDestroyEvent event) {doSomeCleanUp();    }@Inject protectedEventManagereventManager;protectedvoid buy() {eventManager.notify(MyOtherActivity.this, newMyBuyEvent() );    }protectedvoidhandleBuy(@ObservesMyBuyEventbuyEvent ) {Toast.makeToast(this, "You won't regret it!", Toast.LENGTH_LONG).show();    }    //The event class can be anything you wantpublicclassMyBuyEvent {        ...}
ViewsУстранение лишнего,повторяющегося от активити к активити нудного тупого обезьяньего кодаfindViewById(R.id.damn_view_id) в onCreate()5/7/2011cool footer is not a crime14@InjectView(R.id.server_search_button_panel)ViewSwitchersearchButtonSwitcher;@InjectView(R.id.server_selector)Spinner serverSelector;@InjectView(R.id.server_search_button) Button searchButton;@InjectView(R.id.client_music_mode_button) Button musicModuleButton;
LoggingRoboGuice'sLn loggerОтличный формат вызоваАвтоматическое отключение debug и verbose логов при release-ой сборкеВ тэге лога сам пишет класс и номер строки кодаМожно легко переопределить формат отображения и перенаправить вывод лога в файл5/7/2011we footers hate each other15Ln.d("text");Ln.d("formatted %s", "text");Ln.d(exception, "reason %s", "text");
Спасибо за вниманиеПрезентацию подготовилШауберт Александр shaubert.alexander@gmail.com    Специально для Android May Days 20115/7/2011and who will say thanks to footer16

RoboGuice

  • 1.
    RoboGuicewell-known DI frameworkfor Android5/7/20111Android May Days 2011
  • 2.
    Dependency InjectionУстранение зависимостейв кодеЗамена паттерна new()Избавление от рутины создания фабрик, заводов и цеховВозможность использования нескольких конфигурацийОграничение кол-ва инстанций классаУпрощение тестирования5/7/2011Android May Days2
  • 3.
    RoboGuicehttp://code.google.com/p/roboguice/Первым делом, этоDI фрэймворк, который также позволяет:@InjectView()@InjectResource()@InjectPreference()@Inject System Services@ObservesEvents5/7/2011I’m footer and nobody reads me3
  • 4.
    Injecting RoboGuiceСкачатьRoboGuice 1.1.1и guice-2.0-no_aop.jar и подключить их к проекту. Или есть прекрасная возможность начать пользоваться Maven’ом (чего я еще не сделал)Добавить в проект класс наследник RoboApplication и прописать его в AndroidManifest.xlmв тэге application значением параметра android:name (“.MyRoboApplication”)5/7/2011Damn footer live4
  • 5.
    Application Code Sample5/7/2011publicclassDiscoBoxApplicationextendsRoboApplication{@OverrideprotectedvoidaddApplicationModules(List<Module> modules) {modules.add(newNetSocketModule());modules.add(newDiscoBoxModule());super.addApplicationModules(modules); }}I’m a poop-poor footer, no one likes me5
  • 6.
    ModulesПроисходит настройка bind-инговклассов на конкретные объектыСтатическая инициализация5/7/2011I could be a header6bind(Client.class).to(SocketClient.class);@Providespublic Client provideClient() { Client c = newSocketClient();requestInjection(c);return c;}requestStaticInjection(ClientServiceAPI.class);
  • 7.
    Module Sample5/7/2011footer sample7publicclassNetSocketModuleextendsAbstractModule{publicstaticfinal String SERVER_BROADCAST_IN_PORT = "SERVER_BROADCAST_IN_PORT";publicstaticfinal String SERVER_BROADCAST_OUT_PORT = "BROADCAST_OUT_PORT";publicstaticfinal String SO_TIMEOUT = "SO_TIMEOUT";privatestaticfinalintSERVER_BROADCAST_IN_PORT_VALUE = 2012;privatestaticfinalintSERVER_BROADCAST_OUT_PORT_VALUE = 2013;privatestaticfinalintSO_TIMEOUT_VALUE = 20 * 1000;@Overrideprotectedvoid configure() { bind(ProtocolProcessor.class).to(DefaultProtocolProcessor.class); bind(Connection.class).to(DefaultConnection.class); bind(Client.class).to(SocketClient.class); bind(Server.class).to(SocketServer.class).in(Scopes.SINGLETON); bind(ServerFinder.class).to(SocketServerFinder.class); bind(Integer.class).annotatedWith(Names.named(SO_TIMEOUT)) .toInstance(SO_TIMEOUT_VALUE); bind(Integer.class).annotatedWith(Names.named(SERVER_BROADCAST_IN_PORT)) .toInstance(SERVER_BROADCAST_IN_PORT_VALUE); bind(Integer.class).annotatedWith(Names.named(SERVER_BROADCAST_OUT_PORT)) .toInstance(SERVER_BROADCAST_OUT_PORT_VALUE); }}
  • 8.
    InjectingС помощью @InjectCпомощью Injector5/7/2011blah-blah-blah8 @Injectprotected Injector injector;@InjectpublicSocketServer(@Named(NetSocketModule.SERVER_PORT) intport) { ...}@InjectpublicvoidsetProtocolProcessor(ProtocolProcessor processor) {this.processor = processor;}Connection connection = injector.getInstance(Connection.class);
  • 9.
    Lazy InjectionИспользование интерфейсаProvider<T>5/7/2011and lazy footer9@Injectpublic Provider<Server> serverProvider;publicvoidmethodRequersServer() { Server servet = serverProvider.get();...}
  • 10.
    ScopesМожно пометить классаннотацией @Singleton, для ограничения кол-ва инстанций тяжелого ресурсоемкого класса5/7/2011scopes looks like footer friends10@SingletonpublicclassSocketServerimplements Server {...}
  • 11.
    Constructors with paramsИспользованиеаннотаций и специальных биндингов5/7/2011what footers are good for?11@InjectpublicSocketServer(@Named(NetSocketModule.SERVER_PORT) int port, @Named(NetSocketModule.SERVER_BROADCAST_ADDRESS) String broadcastAddress,@Named(NetSocketModule.SERVER_BROADCAST_IN_PORT) intbroadcastInPort,@Named(NetSocketModule.SERVER_BROADCAST_OUT_PORT) intbroadcastOutPort) {}@Overrideprotectedvoid configure() { ...bind(Integer.class).annotatedWith(Names.named(SERVER_BROADCAST_IN_PORT)) .toInstance(SERVER_BROADCAST_IN_PORT_VALUE);bind(Integer.class).annotatedWith(Names.named(SERVER_BROADCAST_OUT_PORT)) .toInstance(SERVER_BROADCAST_OUT_PORT_VALUE);bind(String.class).annotatedWith(Names.named(SERVER_BROADCAST_ADDRESS)) .toInstance(SERVER_BROADCAST_ADDRESS_VALUE);}
  • 12.
    Constructors with paramsИспользование@Provides в модуле5/7/2011footer is watching you12@Provides Server provideServer() { Server server = newSocketServer(2011, "224.0.0.0", 2013, 2014);requestInjection(server);return server; }
  • 13.
    EventsИспользовать уже готовыесобытий или написать свои5/7/2011footer, simple as is13publicvoidperformShutDown(@ObservesOnDestroyEvent event) {doSomeCleanUp(); }@Inject protectedEventManagereventManager;protectedvoid buy() {eventManager.notify(MyOtherActivity.this, newMyBuyEvent() ); }protectedvoidhandleBuy(@ObservesMyBuyEventbuyEvent ) {Toast.makeToast(this, "You won't regret it!", Toast.LENGTH_LONG).show(); } //The event class can be anything you wantpublicclassMyBuyEvent { ...}
  • 14.
    ViewsУстранение лишнего,повторяющегося отактивити к активити нудного тупого обезьяньего кодаfindViewById(R.id.damn_view_id) в onCreate()5/7/2011cool footer is not a crime14@InjectView(R.id.server_search_button_panel)ViewSwitchersearchButtonSwitcher;@InjectView(R.id.server_selector)Spinner serverSelector;@InjectView(R.id.server_search_button) Button searchButton;@InjectView(R.id.client_music_mode_button) Button musicModuleButton;
  • 15.
    LoggingRoboGuice'sLn loggerОтличный форматвызоваАвтоматическое отключение debug и verbose логов при release-ой сборкеВ тэге лога сам пишет класс и номер строки кодаМожно легко переопределить формат отображения и перенаправить вывод лога в файл5/7/2011we footers hate each other15Ln.d("text");Ln.d("formatted %s", "text");Ln.d(exception, "reason %s", "text");
  • 16.
    Спасибо за вниманиеПрезентациюподготовилШауберт Александр shaubert.alexander@gmail.com Специально для Android May Days 20115/7/2011and who will say thanks to footer16

Editor's Notes

  • #14 OnActivityResultEventOnConfigurationChangedEventOnContentChangedEventOnContentViewAvailableEventOnCreateEventOnDestroyEventOnNewIntentEventOnPauseEventOnRestartEventOnResumeEventOnStartEventOnStopEvent