Knight
František Gažo
to the Rescue...
MVP knižnica s Dependency Injection pre Android
Problém
Stavy
Špagetový kód
Ako na to?
MVP
Model
View
Presenter
- Model zabezpečuje prístup k dátam a manipuláciu s nimi
- View zobrazuje dáta (užívateľské rozhranie)
- Presenter reaguje na udalosti od užívateľa a vykonáva zmeny v modeli alebo view
DI
-
Dependency Injection
- odobrať triedam zodpovednosť za získavanie objektov, ktoré potebujú pre svoju činnosť (tzv. služieb)
- poskytnúť pri vytvorení
Ale...
Ako
Knight?
Knight
- knižnica poskytujúca MVP s DI
- využíva:
- DI - Dependency Injection
- APT - Annotation Processing Tool
- ByteCode Weaving
- Gradle Plugin
Knight - Dagger2
Application Scope
Screen Scope
Activity Scope
- konfiguračné triedy automaticky vytvárané (Component, Module)
- vytvára 3 vrstvy (tzv. scopes)
- každá môže poskytovať objekty
- má dostupné objekty zo svojho a obaleného scopu
APT & Bytecode Weaving
Annotation Processing
ByteCode Weaving
- vykonávané počas kompilácie
- APT generuje triedy
- Bytecode Weaving vkladá iba volania metód
- plne debugovateľné
- žiadna reflexia
APT & Bytecode Weaving
- potrebný na spustenie Bytecode Weavingu
- zjednodušuje použitie knižnice
Knight - Gradle Plugin
buildscript {
dependencies {
repositories {
mavenCentral()
}
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
classpath 'eu.inloop.knight:knight-plugin:0.0.4'
}
}
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
apply plugin: 'knight'
API
Inicializácia
@KnightApp
public class App extends Application {
}
@KnightApp
public class App extends Application {
@Inject SomeUtil mUtil;
@Override
protected void onCreate() {
super.onCreate();
// Dostupne Injecty
}
}
- označiť Application ako @KnightApp
- automaticky injectnuté
Activity
@KnightActivity
public class MyActivity extends Activity {
@Inject SomeUtil mUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Dostupne Injecty
}
}
@KnightActivity
public class MyActivity extends Activity {
}
- stačí označiť ako @KnightActivity
- automaticky injectnuté
Fragment / Custom View
public class CustomView extends View {
@Inject SomeUtil mUtil;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
// Dostupne Injecty
}
}
public class MyFragment extends Fragment {
@Inject SomeUtil mUtil;
@Override
protected void onAttach() {
super.onAttach();
// Dostupne Injecty
}
}
- trieda sa neoznačuje anotáciou
- automaticky injectnuté
@KnightActivity({
MyFragment.class,
CustomView.class
})
public class MyActivity extends Activity {
//...
}
Service
public class SomeService extends IntentService {
@Inject SomeUtil mUtil;
public SomeService() {
super("SomeName");
// Dostupne Injecty
}
// ...
}
- trieda sa neoznačuje anotáciou
- automaticky injectnuté
@KnightApp(
SomeService.class
)
public class App extends Application {
//...
}
Ako poskytovať objekty?
public class SomeUtil {
@AppProvided
@Singleton
public SomeUtil(Application app) {
//...
}
// ...
}
- 3 anotácie:
- @AppProvided
- @ScreenProvided
- @ActivityProvided
public class UiUtil {
@ActivityProvided({
ExampleActivity.class
})
@Singleton
public UiUtil(Activity activity) {
//...
}
// ...
}
Ako poskytovať objekty?
@Module
public class MyModule {
@Provides
public SomeObject providesObject(/* args */) {
return new SomeObject(/* args */);
}
}
- vlastný Dagger Module
- tiež označiť s @App/Screen/ActivityProvided
- používať príslušný scope:
- @AppScope
- @ScreenScope
- @ActivityScope
@AppProvided
@Module
public class MyModule {
@Provides
public SomeObject providesObject(/* args */) {
return new SomeObject(/* args */);
}
}
@AppProvided
@Module
public class MyModule {
@Provides
@AppScope
public SomeObject providesObject(/* args */) {
return new SomeObject(/* args */);
}
}
Kde je MVP?
Presenter
public class ContactPresenter extends BasePresenter<IContactView> {
@ScreenProvided(ContactActivity.class)
@Singleton
public ContactPresenter(...) {...}
@Override
public void onCreate(@Nullable Bundle savedState) {...}
@Override
public void onSave(@NonNull Bundle outState) {...}
@Override
public void onRemove() {...}
@Override
public void onBindView(@NonNull V view) {...}
@Override
public void onReleaseView() {...}
}
- 2 možnosti vytvorenia:
- extends BasePresenter<T extends IView>
- implements IPresenter<T extends IView>
View
public interface IContactView
extends IView {
void show(Contact c);
void show(String msg);
}
public class ContactView extends View implements IContactView {
@Inject ContactPresenter mPresenter;
public ContactView(Context c, ...) {
super(c, ...);
}
@Override
public void show(String msg) {...}
@Override
public void show(Contact c) {...}
}
- definovať rozhranie
- implementovať
- nastaviť view
- uvoľniť view
public class ContactView extends View implements IContactView {
@Inject ContactPresenter mPresenter;
public ContactView(Context c, ...) {
super(c, ...);
// nastav view
mPresenter.bindView(this);
}
@Override
public void show(String msg) {...}
@Override
public void show(Contact c) {...}
}
public class ContactView extends View implements IContactView {
@Inject ContactPresenter mPresenter;
public ContactView(Context c, ...) {
super(c, ...);
// nastav view
mPresenter.bindView(this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// uvolni view
mPresenter.releaseView();
}
@Override
public void show(String msg) {...}
@Override
public void show(Contact c) {...}
}
Extra
Extra
@KnightActivity
public class ContactActivity extends Activity {
@Extra
Contact mContact;
//...
}
public class ContactListActivity extends Activity {
public void showContact(Contact contact) {
I.startContactActivity(this, contact);
}
// ...
}
-
trieda I pre navigáciu medzi Activitami
-
2 metódy pre každú activity:
-
Intent forXActivity(Context c[, T extra, ...])
-
void startXActivity(Context c[, T extra, ...])
-
Čo ďalej?
Ciele
- Optimalizovať vytvárané triedy
- Podpora pre mockovanie
- Podpora pre Assisted Injection
- Testovať
Ďakujem za pozornosť
Q&A
Knight to the rescue
By František Gažo
Knight to the rescue
Kinght, MVP library with Dependency Injection for Android
- 819