Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Customization. How to?

Customization. How to?

Dmitriy Movchan

October 31, 2018
Tweet

More Decks by Dmitriy Movchan

Other Decks in Programming

Transcript

  1. • Выпускник МГТУ им. Баумана Кафедра «Компьютерные системы и сети»

    ИУ6 • Выпускник Технопарк (park.mail.ru) «Системный архитектор» • Ментор в Android Academy MSK • Android разработчик в Kasperky Lab Kaspersky Internet Security for Android Мовчан Дмитрий 2
  2. 9 Продукты, которые давно на рынке и зарекомендовали себя Например

    из Лаборатории Касперского: • Kaspersky Internet Security for Android • Kaspersky Safe Kids • Kaspersky Secure Connection Где создают кастомизации
  3. 13 1) Локализация на разные языки (в нашем продукте их

    16) email поддержки, название заказчика 2) Перекраска другие цвета кнопок, текста 3) Бизнес логика другое поведение на каких-то экранах, новый функционал Что вызвало грусть?
  4. 17 Flavor-way android { … flavorDimensions "app" productFlavors { product

    { applicationId "mybestapp" versionName "1.0" flavorDimensions "app" } custom { applicationId "mybestapp.custom" versionName "1.0-custom" flavorDimensions "app" } } } build.gradle
  5. 19 Flavor-way public class ClassThatReturnCorrectString { static String correctString =

    “product"; } public class ClassThatReturnCorrectString { static String correctString = "custom"; } someText.setText(correctString);
  6. 27 main partner1 public abstract class DefaultLogic implements CustomLogic {

    public String customStringOnTextView() { return null; } public boolean shouldShowMessage() { return true; } } public class Partner1Logic extends DefaultLogic { @Override public String customStringOnTextView() { return "Custom"; } }
  7. 28

  8. 29 main public class CustomInterfaceWrapper<T> { T customInterface; public CustomInterfaceWrapper(T

    i) { customInterface = i; } public boolean isAvailable() { return customInterface != null; } public T get() { if (!isAvailable()) { throw new AssertionError("Interface is not available"); } return customInterface; } }
  9. 30 main partnerANY @Module public class CustomModule { @Provides @Singleton

    CustomInterfaceWrapper<CustomLogic> provideCustomLogic() { return new CustomInterfaceWrapper<>(null); } } public class FlavorCustomModule extends CustomModule { } main appComponent = DaggerAppComponent.builder() .commonModule(new FlavorCustomModule()) .build();
  10. 31

  11. 32 partner1 public class FlavorCustomModule extends CustomModule { @Override CustomInterfaceWrapper<CustomLogic>

    provideCustomLogic() { return new CustomInterfaceWrapper<CustomLogic>(new Partner1Logic()); } } main @Inject CustomInterfaceWrapper<CustomLogic> mCustomLogic; ... TextView someText = findViewById(R.id.text_view); if (mCustomLogic.isAvailable()) { String customText = mCustomLogic.get().customStringOnTextView(); if (customText != null) { someText.setText(customText); } }
  12. 33

  13. 34

  14. 35 <string name="str_enter_code_toast">Enter the secret code for Kaspersky Internet Security

    for Android:</string> <string name="str_license_expired_info_text_body"> Kaspersky Internet Security for Android switched to the free version.</string> <string name="str_app_loading">Starting Kaspersky Internet Security for Android</string> <string name="str_big_res_wizard_incompatible_apps_title">Apps incompatible with Kaspersky Internet Security for Android detected</string> <string name="str_agreements_title">Before using Kaspersky Internet Security for Android, please read and accept the following documents:</string> Строчки
  15. 36 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [ <!ENTITY Product_name "Kaspersky

    Internet Security for Android"> ]> <resources> … <string name="str_enter_code_toast">Enter the secret code for &Product_name;:</string> <string name="str_license_expired_info_text_body"> &Product_name; switched to the free version.</string> <string name="str_app_loading">Starting &Product_name;</string> Строчки
  16. 37 Strings.xml: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [ <!ENTITY Product_name

    "{{Product_name}}"> ]> Entities.xml: <entities> <Product_name>Kaspersky Internet Security for Android</Product_name> </entities> + gradle task magic Строчки
  17. 41

  18. 42  120 цветов только в colors  Огромное количество

    цветов внутри самих layout  Почти 100 стилей в styles  > 80 непонятных размеров <dimen name="info_text_wrapper_horizontal_padding">32dp</dimen> <dimen name="locked_content_horizontal_margin">@dimen/dp32</dimen>  И это только в main (не учитывая кастомизации) Как было раньше (до UIKit)
  19. 47 Как layout выглядит теперь <TextView android:id="@+id/text_view_gdpr_terms_and_conditions_main" style="?attr/uikitTextBody1Secondary" android:textColor="?uikitColorTextSecondary" android:layout_width="0dp"

    android:layout_height="wrap_content" android:layout_marginTop="8dp"/> <Button android:id="@+id/button_gdpr_terms_and_conditions_confirm" style="?attr/uikitButtonColored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="24dp" android:text="@string/all_confirm"/>
  20. 48 Как теперь перекрашивается кастомизация colors.xml <resources> <!--customization--> <color name="uikit_base_green">#a01dff</color>

    <color name="uikit_active_green">#6800ca</color> <color name="uikit_contrast_green">#d75bff</color> </resources>
  21. 51 Кастомизации обновляются не каждый релиз, а иногда с большим

    промежутком времени, из-за этого какой-то период времени их никто не поддерживает. Когда настает время их собрать – получаем compilation ошибки, т.к. код уже банально не компилируется. CustomLogic – инжектится где только можно, AppComponent невероятных размеров. Что сейчас улучшаем
  22. 52 Решение… хранить весь кастомизируемый код внутри main пакета. Во

    flavor лежат только json файлы конфигов. Как улучшить public class Partner1Logic extends DefaultLogic { @Override public String customStringOnTextView() { return "Custom"; } } { "customStringOnTextView": "Custom" }
  23. 53 Создание CustomInteractor, который будет менять модели необходимые для каких

    либо фичей на разных слоях архитектуры. Как улучшить dagger dagger dagger
  24. Let’s Talk? https://t.me/v1sar Kaspersky Lab HQ 39A/3 Leningradskoe Shosse Moscow,

    125212, Russian Federation Tel: +7 (495) 797-8700 www.kaspersky.com
  25. 55

  26. 56 partner2 public class FlavorCustomModule extends CustomModule { @Override CustomInterfaceWrapper<CustomLogic>

    provideCustomLogic() { return new CustomInterfaceWrapper<CustomLogic>(new Partner2Logic()); } } public class Partner2Logic extends DefaultLogic { @Override public boolean shouldShowMessage() { return false; } } main public abstract class DefaultLogic implements CustomLogic { public String customStringOnTextView() { return null; } public boolean shouldShowMessage() { return true; } }