Slide 1

Slide 1 text

΅͘ʹ΋Ͱ͖ͨ "OOPUBUJPO1SPDFTTJOH !GVTIJSPZBNB

Slide 2

Slide 2 text

ͳʹ͕Ͱ͖Δ͔ w ΞϊςʔγϣϯΛݩʹίϯύΠϧ࣌ʹίʔυੜ੒Ͱ ͖Δ w ͦΕ͚ͩʜ

Slide 3

Slide 3 text

ͳʹ͕Ͱ͖Δ͔ w ΞϊςʔγϣϯΛݩʹίϯύΠϧ࣌ʹίʔυੜ੒Ͱ ͖Δ w ͦΕ͚ͩʜ ܕ҆શ ଎౓ͷ٘ਜ਼͕ͳ͍ ੜ੒͞Εͨίʔυ͕ ಡΊΔͷͰ҆৺

Slide 4

Slide 4 text

ͳʹ͕Ͱ͖ͳ͍͔ w طଘͷίʔυ͕มߋͰ͖ΔΘ͚Ͱ͸ͳ͍ w ੜ੒͞ΕͨίʔυΛͦͷ··࢖͏ w ੜ੒͞ΕͨίʔυʹॲཧΛҕৡ͢Δ

Slide 5

Slide 5 text

༻్ w ϘΠϥʔϓϨʔτͷ࡟ݮ w ܕม׵ɺϚοϐϯά

Slide 6

Slide 6 text

ར༻ྫ " ੜ੒͞ΕͨίʔυΛͦͷ··ར༻͢ΔλΠϓ w "OESPJE"OOPUBUJPOT FUDʜ # ॲཧΛҕৡ͢ΔλΠϓ w #VUUFS,OJGF 1FSNJTTJPOT%JTQBUDIFS FUDʜ

Slide 7

Slide 7 text

ར༻ྫ " ੜ੒͞ΕͨίʔυΛͦͷ··ར༻͢ΔλΠϓ w "OESPJE"OOPUBUJPOT FUDʜ # ॲཧΛҕৡ͢ΔλΠϓ w #VUUFS,OJGF 1FSNJTTJPOT%JTQBUDIFS FUDʜ Ҡৡͷίʔυ͕ෆཁ͕ͩ ར༻ଆͰੜ੒͞ΕͨίʔυΛҙࣝ͢Δඞཁ͕͋Δ .BOJGFTUʹొ࿥͕ඞཁ౳ Ҡৡͷίʔυ͕ඞཁ͕ͩ ݩΫϥε͸ͦͷ··ͰΑ͍

Slide 8

Slide 8 text

)PXUP.BLF

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

MJCSBSZNPEVMF w +BWB-JCSBSZ"OESPJE-JCSBSZ w "OOPUBUJPOΫϥε΍ϥΠϒϥϦͱͯ͠ఏڙ͢Δ࣮ॲཧΛ ॻ͍ͨΫϥε͕ॴଐ w +BWB POMZ+BDL w ίϯύΠϧ࣌ͷΈඞཁͳ৔߹͸QSPWJEFE w BQQϞδϡʔϧ͔ΒϥΠϒϥϦͷίʔυΛࢀর͢Δ৔߹ ͸DPNQJMF

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

QSPDFTTPSNPEVMF w +BWB-JCSBSZ w "OOPUBUJPO1SPDFTTPSͱͦΕʹ෇ਵ͢ΔΫϥε܈ w +BWB,PUMJO XIBUFWFS w MJCSBSZϞδϡʔϧΛDPNQJMFࢦఆͰࢀর w BQQϞδϡʔϧ͔Β͸BOOPUBUJPO1SPDFTTPSࢦఆ

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

TBNQMFNPEVMF w "OESPJE"QQ.PEVMF w ඞਢͰ͸ͳ͍͕ಈ࡞֬ೝ΍αϯϓϧͱͯ͠ศར annotationProcessor project(':processor')
 compile project(':library')
 // or
 provided project(':library')

Slide 16

Slide 16 text

@Target({ElementType.TYPE, ElementType.FIELD})
 @Retention(RetentionPolicy.CLASS)
 public @interface MyCoolAnnotation {
 } MJCSBSZNPEVMF

Slide 17

Slide 17 text

@Target({ElementType.TYPE, ElementType.FIELD})
 @Retention(RetentionPolicy.CLASS)
 public @interface MyCoolAnnotation {
 } MJCSBSZNPEVMF ΞϊςʔγϣϯΛ͚ͭΒΕΔՕॴ Ξϊςʔγϣϯ͕࢒Δظؒ

Slide 18

Slide 18 text

@MyCoolAnnotation
 public class SampleClass {
 @MyCoolAnnotation
 final String text;
 
 public SampleClass(String text) {
 this.text = text;
 }
 } TBNQMFNPEVMF

Slide 19

Slide 19 text

QSPDFTTPSNPEVMF dependencies {
 compile project(":library")
 compile 'com.squareup:javapoet:1.8.0'
 compile 'com.google.auto.service:auto-service:1.0-rc2'
 }

Slide 20

Slide 20 text

QSPDFTTPSNPEVMF dependencies {
 compile project(":library")
 compile 'com.squareup:javapoet:1.8.0'
 compile 'com.google.auto.service:auto-service:1.0-rc2'
 } ίʔυੜ੒ϥΠϒϥϦ ίϯύΠϧ࣌ʹࣗಈతʹ1SPDFTTPSΛ࣮ߦ

Slide 21

Slide 21 text

QSPDFTTPSNPEVMF dependencies {
 compile project(":library")
 compile 'com.squareup:javapoet:1.8.0'
 compile 'com.google.auto.service:auto-service:1.0-rc2'
 compile 'com.google.android:android:4.1.1.4'
 }
 sourceSets {
 main {
 java {
 srcDirs = [‘src/main/java', '../library/src/main/java']
 }
 }
 }

Slide 22

Slide 22 text

QSPDFTTPSNPEVMF dependencies {
 compile project(":library")
 compile 'com.squareup:javapoet:1.8.0'
 compile 'com.google.auto.service:auto-service:1.0-rc2'
 compile 'com.google.android:android:4.1.1.4'
 }
 sourceSets {
 main {
 java {
 srcDirs = [‘src/main/java', '../library/src/main/java']
 }
 }
 } BOESPJEMJCSBSZΛࢀর͢Δ৔߹ BOESPJEMJCSBSZΛࢀর͢Δ৔߹

Slide 23

Slide 23 text

@AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF

Slide 24

Slide 24 text

@AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF 1SPDFTTPS͸͜ͷந৅ΫϥεΛܧঝͯ͠ ࡞Δͷ͕ศར

Slide 25

Slide 25 text

@AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF ίϯύΠϧ࣌ʹ͜ͷ1SPDFTTPS͕࣮ߦ͞ΕΔ

Slide 26

Slide 26 text

@AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF ॲཧର৅ͷΞϊςʔγϣϯΛ4FUͰࢦఆ

Slide 27

Slide 27 text

@AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF αϙʔτ্ݶͷ+BWBόʔδϣϯ

Slide 28

Slide 28 text

@AutoService(Processor.class)
 public class MyProcessor extends AbstractProcessor {
 @Override
 public Set getSupportedAnnotationTypes() {
 return ImmutableSet.of(MyCoolAnnotation.class.getName());
 }
 
 @Override
 public SourceVersion getSupportedSourceVersion() {
 return SourceVersion.latest();
 }
 
 @Override
 public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
 return false;
 }
 } QSPDFTTPSNPEVMF ϓϩηοαʔʹΑΔॲཧຊମ

Slide 29

Slide 29 text

QSPDFTT w QSPDFTT ϝιου͸ॲཧ͢ΔΞϊςʔγϣϯʹԠ ͯ͡ෳ਺ճݺ͹ΕΔɻ͜ΕΛϥ΢ϯυͱ͍͏ɻ w ֤ϥ΢ϯυͰੜ੒͞ΕͨιʔεΛݩʹ͞Βʹ࣍ͷϥ ΢ϯυ͕࣮ߦ͞ΕΔʢ࠷௿ϥ΢ϯυʣ w ͜͜ͰΞϊςʔγϣϯʹԠͯ͡೚ҙͷॲཧΛ΄Ͳ͜ ͠ɺϑΝΠϧʹग़ྗ͢Δɻ

Slide 30

Slide 30 text

QSPDFTTPSNPEVMF private Elements elementUtils;
 private Types typeUtils;
 private Messager messager;
 private Filer filer;
 
 @Override
 public synchronized void init(ProcessingEnvironment processingEnvironment) {
 super.init(processingEnvironment);
 
 elementUtils = processingEnvironment.getElementUtils();
 typeUtils = processingEnvironment.getTypeUtils();
 messager = processingEnvironment.getMessager();
 filer = processingEnvironment.getFiler();
 } ศརͳϢʔςΟϦςΟ܈

Slide 31

Slide 31 text

QSPDFTTPSNPEVMF TypeElement classElement = roundEnvironment.getElementsAnnotatedWith(MyCoolAnnotation.class)
 .stream()
 .filter(element -> element.getKind() == ElementKind.CLASS)
 .map(element -> (TypeElement) element)
 .findFirst()
 .get();
 
 String className = classElement.getSimpleName().toString();
 
 TypeSpec typeSpec = TypeSpec.classBuilder("Sub" + className).build();
 JavaFile javaFile = JavaFile.builder("com.example", typeSpec).build();
 try {
 javaFile.writeTo(filer);
 } catch (IOException e) {
 messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage());
 } ΞϊςʔγϣϯʹରԠ͢Δཁૉ

Slide 32

Slide 32 text

QSPDFTTPSNPEVMF TypeElement classElement = roundEnvironment.getElementsAnnotatedWith(MyCoolAnnotation.class)
 .stream()
 .filter(element -> element.getKind() == ElementKind.CLASS)
 .map(element -> (TypeElement) element)
 .findFirst()
 .get();
 
 String className = classElement.getSimpleName().toString();
 
 TypeSpec typeSpec = TypeSpec.classBuilder("Sub" + className).build();
 JavaFile javaFile = JavaFile.builder("com.example", typeSpec).build();
 try {
 javaFile.writeTo(filer);
 } catch (IOException e) {
 messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage());
 } ΫϥεΛऔಘ

Slide 33

Slide 33 text

QSPDFTTPSNPEVMF TypeElement classElement = roundEnvironment.getElementsAnnotatedWith(MyCoolAnnotation.class)
 .stream()
 .filter(element -> element.getKind() == ElementKind.CLASS)
 .map(element -> (TypeElement) element)
 .findFirst()
 .get();
 
 String className = classElement.getSimpleName().toString();
 
 TypeSpec typeSpec = TypeSpec.classBuilder("Sub" + className).build();
 JavaFile javaFile = JavaFile.builder("com.example", typeSpec).build();
 try {
 javaFile.writeTo(filer);
 } catch (IOException e) {
 messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage());
 } +BWBΫϥεΛੜ੒

Slide 34

Slide 34 text

QSPDFTTPSNPEVMF ੜ੒͞Εͨʂ package com.example;
 
 class SubSampleClass {
 }

Slide 35

Slide 35 text

&MFNFOU w ΫϥεɺϝιουɺϑΟʔϧυͳͲͷཁૉΛදݱ͢ ΔΫϥε w 5ZQF&MFNFOUʜΫϥε౳ w &YFDVUBCMF&MFNFOUʜϝιου w 7BSJBCMF&MFNFOUʜ౳ʑ

Slide 36

Slide 36 text

5ZQF.JSSPS w ܕ৘ใ w ྫ͑͹ΞϊςʔγϣϯʹରԠ͢ΔϑΟʔϧυΛऔಘ ͨ͠ͱͯ͠ɺͦͷܕΛऔಘ͍ͨ࣌͠ͳͲʹ࢖͏ w &MFNFOUBT5ZQF

Slide 37

Slide 37 text

KBWBQPFU w TRVBSF੡ͷίʔυੜ੒ΞγετϥΠϒϥϦ w "OOPUBUJPO1SPDFTTJOHͰίʔυੜ੒͢Δ্Ͱ ೥ݱࡏσϑΝΫτͰ͋Γඞਢͱߟ͑Δ w ͱͯ΋ॻ͖͖Εͳ͍ͷͰৄ͘͠͸IUUQT HJUIVCDPNTRVBSFKBWBQPFU

Slide 38

Slide 38 text

KBWBQPFU w 5ZQF4QFDʜܕΛੜ੒ w .FUIPE4QFDʜϝιουΛੜ੒ w 1BSBNFUFS4QFDʜύϥϝʔλΛੜ੒ w 'JFME4QFDʜϑΟʔϧυΛੜ੒

Slide 39

Slide 39 text

΅͘ʹ΋Ͱ͖ͨ w $VDLPP w IUUQTHJUIVCDPNTSZNDVDLPP w 7VMUVSF w IUUQTHJUIVCDPNTSZNWVMUVSF

Slide 40

Slide 40 text

$VDLPP w %FMFHBUJPO1BUUFSOΛ؆୯ʹ࣮૷͢ΔϥΠϒϥϦ w ,PUMJOͷ$MBTT%FMFHBUJPOʹண૝Λಘͨ

Slide 41

Slide 41 text

public interface Greeter { String sayHello(); String sayHello(String toWhom); } public class EnglishGreeter implements Greeter { @Override public String sayHello() { return sayHello("ANONYMOUS"); } @Override public String sayHello(String toWhom) { return String.format("Hello %s !", toWhom); } } $VDLPP ΠϯλϑΣʔε

Slide 42

Slide 42 text

public interface Greeter { String sayHello(); String sayHello(String toWhom); } public class EnglishGreeter implements Greeter { @Override public String sayHello() { return sayHello("ANONYMOUS"); } @Override public String sayHello(String toWhom) { return String.format("Hello %s !", toWhom); } } $VDLPP ࣮૷

Slide 43

Slide 43 text

@Delegate public abstract class EnglishGreeterWithRecording implements Greeter { @By final EnglishGreeter englishGreeter = new EnglishGreeter(); @Override public String sayHello(String toWhom) { // do anything you like here return englishGreeter.sayHello(toWhom); } } $VDLPP

Slide 44

Slide 44 text

@Delegate public abstract class EnglishGreeterWithRecording implements Greeter { @By final EnglishGreeter englishGreeter = new EnglishGreeter(); @Override public String sayHello(String toWhom) { // do anything you like here return englishGreeter.sayHello(toWhom); } } $VDLPP !"CTUSBDU !%FMFHBUF

Slide 45

Slide 45 text

@Delegate public abstract class EnglishGreeterWithRecording implements Greeter { @By final EnglishGreeter englishGreeter = new EnglishGreeter(); @Override public String sayHello(String toWhom) { // do anything you like here return englishGreeter.sayHello(toWhom); } } $VDLPP JNQMFNFOUT

Slide 46

Slide 46 text

@Delegate public abstract class EnglishGreeterWithRecording implements Greeter { @By final EnglishGreeter englishGreeter = new EnglishGreeter(); @Override public String sayHello(String toWhom) { // do anything you like here return englishGreeter.sayHello(toWhom); } } $VDLPP ੜ੒͞ΕͨΫϥε͸ ະ࣮૷ͷϝιου͸ !#Zम০ͨ͠Πϯελϯεʹ ͢΂ҕৡ͞ΕΔ

Slide 47

Slide 47 text

$VDLPP OFX*OTUBODF Ͱऔಘ // in your code EnglishGreeterWithRecording greeter = EnglishGreeterWithRecordingImpl.newInstance(new EnglishGreeter());

Slide 48

Slide 48 text

annotationProcessor ‘us.shiroyama.android:cuckoo-processor:0.1.0' provided 'us.shiroyama.android:cuckoo:0.1.0' $VDLPP

Slide 49

Slide 49 text

7VMUVSF w ίʔϧόοΫΛϥΠϑαΠΫϧ಺Ͱ҆શʹѻ͏ͨΊ ͷϥΠϒϥϦ w 'SBHNFOU5SBOTBDUJPODPNNJUͷ *MMFHBM4UBUF&YDFQUJPOΛى͖ͳ͘͢Δ

Slide 50

Slide 50 text

void fetchAsynchronously() { /* do heavy asynchronous task here */ doCallback("finished!"); } void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } 7VMUVSF

Slide 51

Slide 51 text

void fetchAsynchronously() { /* do heavy asynchronous task here */ doCallback("finished!"); } void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } 7VMUVSF ඇಉظॲཧ

Slide 52

Slide 52 text

void fetchAsynchronously() { /* do heavy asynchronous task here */ doCallback("finished!"); } void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } 7VMUVSF ίʔϧόοΫ PO1BVTFҎ߱͸Ϋϥογϡ

Slide 53

Slide 53 text

7VMUVSF @ObserveLifecycle public class YourActivity extends AppCompatActivity { void fetchAsynchronously() { SafeMainActivity.doCallbackSafely("finished!"); } @SafeCallback void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } }

Slide 54

Slide 54 text

7VMUVSF @ObserveLifecycle public class YourActivity extends AppCompatActivity { void fetchAsynchronously() { SafeMainActivity.doCallbackSafely("finished!"); } @SafeCallback void doCallback(@NonNull String message) { FinishDialog.newInstance().show(getSupportFragmentManager(), "TAG"); } } !4BGF$BMMCBDL ͔ΘΓʹͪ͜ΒΛݺͼग़͢

Slide 55

Slide 55 text

7VMUVSF @Override protected void onResume() { super.onResume(); SafeMainActivity.register(this); } @Override protected void onPause() { SafeMainActivity.unregister(); super.onPause(); }

Slide 56

Slide 56 text

7VMUVSF @Override protected void onResume() { super.onResume(); SafeMainActivity.register(this); } @Override protected void onPause() { SafeMainActivity.unregister(); super.onPause(); } ҕৡ

Slide 57

Slide 57 text

7VMUVSF annotationProcessor 'us.shiroyama.android:vulture-processor:0.1.0' compile 'us.shiroyama.android:vulture:0.1.0'

Slide 58

Slide 58 text

5IBOLZPV