Naver Tech Concert Day-1

개요

  • 행사명 : Naver Tech Concert

  • URL : http://techcon.naver.com/

  • 일정 : DAY 1- 2018년 11월 1일(목) 10:00 - 17:30

    DAY 2- 2018년 11월 2일(금) 10:00 - 17:30

  • 장소 : 정자동 네이버 그린팩토리 본사 2층 CONNECT HALL

  • 일정 :

    • 11월 1일(목) D AY 1
      09:30 ~ 09:55   참가 등록
      10:00 ~ 10:10   인사말
      10:10 ~ 11:10   Android DataBinding (기초에서 고급까지) 
      11:10 ~ 12:10   MVVM with Grab architecture 
      12:10 ~ 13:30   점심시간 (별도 제공은 없습니다.) 
      13:30 ~ 14:30   디자인 1도 모르는 개발자, UX디자인 시작하기
      14:30 ~ 15:30   Material Design의 철학과 적용 사례
      15:30 ~ 16:30   Android Kotlin을 통한 개발 전략 
      16:30 ~ 17:30   Obfuscation 101: 난독화, 프로가드, R8, 트랜스포머 API
      17:30   마무리
  • 11월 2일(금) DAY 2
       09:30 ~ 09:55  참가 등록
       10:00 ~ 11:00  변화의 시대: 안드로이드 앱 어떻게 개발할 것인가?
       11:00 ~ 12:00  Efficient and Testable MVVM pattern(with using AAC, Rx, Koin)
       12:00 ~ 13:30  점심시간 (별도 제공은 없습니다.)
       13:30 ~ 14:30  내가 사랑한 개발자들
       14:30 ~ 15:30  안드로이드 웹뷰의 모든것 
       15:30 ~ 16:30  안드로이드에서 코루틴은 어떻게 적용할 수 있을까?
       16:30 ~ 17:30  자동화, 계륵에 살 붙이기
       17:30  마무리 

현장


전리품

01. 인사말

900명이 넘는 사람이 신청했으나, 어쩔 수 없이 추천으로 초청하게 됨.

네이버 내부 사내 개발자 역량 강화를 위해 다양한 행사를 진행함.

외부 개발자 초빙하여 부정기적으로 다양한 주제의 테크톡을 진행함.

내부적으로는 주제별로 사내 밋업을 진행하며 가장 활발한 그룹이 자바스크립트 프런트엔드 개발, 안드로이드, iOS 그룹이 활발함.

사내 내외부 교류와 네트워킹을 위해 준비하며, 프런트엔드 그룹은 이미 진행하고 있으며, 이번에 안드로이드 그룹도 진행하게 됨.

안드로이드 단말 나온지 10년이 되는데 여러 노하우를 공유했으면 함.


02. Android DataBinding (기초에서 고급까지)

PRISM Live Studio 앱에서 데이터바인딩을 전면적으로 사용 중.

DataBinding이란?

XML(Screen) <- Java/Kotlin(Data/Logic) 인 부분을***Binding.java가 연결함.

이 부분은 런타임시가 아닌 XML 빌드시 생성됨.

XML에 기존대비 <Layout> 태그 추가 필요.

activity_main.xml -> ActivityMain.xml -> ActivityMainBinding.java

기존 레이아웃을 setContentView 사용하던 방식이 아니라 DataBindingUtil을 이용해 레이아웃을 통해 DataBinding 클래스(예. ActivityMainDataBinding)를 사용.

Activity, Fragment, View(ViewHolder) 등에서 사용 가능

XML을 통해 DataBinding 생성시 그 안의 View들에 대한 참조가 가능함.

Actvitiy 등에서 그 View들을 참조하여 사용이 가능하나 참조를 제거하는 방향으로 하고자 함.

XML에서 DataBinding 사용시 data 변수 추가 필요.

Gradle 3.2.0 미만에는 DataBinding 클래스 내에 구현이 있으나, 이 후부터는 DataBinding 클래스가 abstract 클래스이고 DataBindingImple 클래스에 구현이 들어감.

<layout>
    <data>
        <variable
                  name="model"
                  type="com.test.blabla.SampleModel" />
    </data>
    <LinearLayout
                  ... >
        <TextView
                  ...
                  android:text="@{model.title}" />
    </LinearLayout>
</layout>

데이터바인딩 이루어지는 규칙 (실행 우선 순위 순)

  • BindingAdapter (사용자 지정 Setter)
  • BindingMethod (이름이 바뀐 Setter)
  • Set Method (자동 Setter)

Setter 예제

<TextView
          android:id="@+id/title"
          ...
          android:enabled="@{true}" />

위와 같은 xml 빌드시 ***Binding.java가 아래처럼 생성됨.

this.title.setEnabled(true)

커스텀뷰의 추가된 메소드 등을 위와 같이 사용 가능.

BindingAdapter 예제

바인딩 어댑터를 사용시 애노테이션 사용하면 public static 필수임.

@BindingAdapter(value={"naver"})
public static void naverBindingAdapter(TextView, boolean isNaver) {
    ...
}

위 바인딩 어댑터를 사용하는 xml

<TextView
          android:id="@+id/title"
          ...
          app:naver="@{true}" />

위 xml 빌드시 생기는 ***Binding.java

SampleBindingAdapter.naverBindingAdater(this.title, true);

BindingAdapter 애노테이션 선언부

@Target(ElementType.METHOD)
public @interface BindingAdapter {
    String[] value();
    boolean requireAll() default true;
}
  • value : XML Attribute Name List, 다수 개일 경우 메소드 파라미터 순서와 매칭이 되어야 함.
  • requireAll : value()의 Attribute가 모두 존재할 때만 처리할지 여부. false일 경우 int/double/float/... 등의 타입의 Attribute가 없을 경우는 값은 0, Object 타입의 Attribute가 없을 경우는 null로 처리됨.

발표자께서는 requireAll=false 을 사용하였었으나, 다수 개의 Attribute에서 어떤 값만 옵셔널하게 처리가 안되어 아래와 같이 오버로딩하면서 쓰고 있음.

@BindingAdapter(value={"android:visibility", "animType", "animDuration"})
public static void newAnimationBindingMethod(View view, boolean visibility, @AnimType int animType, int animDuration) { ... }

@BindingAdapter(value={"android:visibility", "animType"})
public static void newAnimationBindingMethod(View view, boolean visibility, @AnimType int animType) { ... }

Observable

XML(Screen) <- ***Binding.java <- Java/Kotlin(Data/Logic)

Java/Kotlin 등에서 변경시 XML에 알려주길 위해 Observable 사용.

(DataBinding이 아니라면 LiveData해도 됨.)

Observable 인터페이스 있으나, 구글에서 사용하기 편하게 BaseObservable 제공함.

public static class SampleModel extends BaseObservalbe {
    private String title;
    public SampleMode(String title) {
        this.title = title;
    }
    public void setTitle(String title) {
        this.title = title;
        notifyPropertyChanged(BR.title);
    }
    @Bindable
    public String getTitlt() {
        return title;
    }
}

위에서 BR은 빌드시 생성이 됨.

위 SampleModel 객체 생성 후 setTitle 메소드 사용시 notifyPropertyChanged()를 통해 ***Binding.java에 변경이 전달 됨.

***Binding.java에서는 getTitle()을 통해 바뀐 값을 전달받음.

그래도 불편하므로 구글에서는 아래와 같은 것들을 제공함

  • ObservableBoolean
  • ObservableByte
  • ObservableChar
  • ...
  • ObservableArrayList
  • ObservableArrayMap
  • ObservableParcelabe
  • ObservableField
    • ObservableField<String>
    • ObservableField<CustomMode>

SampleModel을 바꿔보자.

public static class SampleModel extends BaseObservalbe {
    public final ObservableFiedl<String> title;
    public SampleMode(String title) {
        this.title = new ObservableField<>(title);
    }
}

Listener의 Binding

  • Object 전달

    <Button
            ...
            android:onClick="@{model.clickListener}" />

    위와 같이 사용시 BindingMethod 사용이 필요함

    @BindingMethod(type=View.class, attribute="android:onClick", method="setOnClickListener")
  • Method 직접 연결

    <Button
            ...
            android:onClick="@{model:clickListener}" />
    <Button
            ...
            android:onClick="@{(view)->model.clickListener(view)}" />

    위와 같이 사용시 아래와 같이 사용함.

    public class MainActivity extend AppCompatActivity {
        public void onClicButton(View button) {
            //선언부의 view button은 람다에서 제거 가능
        }
    }

CustomView + Custom Listener

public class CustomTextView extends AppCompatTextView {
    public interface OnCustomEventListener {
        void onEvent();
    }
}
@BindingAdapter("onCustomEvent")
public void setOnCustomEventListener(CustomTextView view, CustomTextView.OnCustomEventListener listener) {
    view.setOnCustomEventListener(listener);
}

//또는 

@BindingMethod({
    @BindingMethod(type=CustomTextView.class, attribute="onCustomEvent", method="setOnCustomEventListener")
})
<com.blabla.CustomTextView
                           ...
                           app:onCustomEvent="@{()->activity.onCustomEvent()}"

리스너 바인딩 사용시 주의점

대부분 리스너들은 return이 void 형식이나 onLongClick 일경우 return이 boolean형식이라 잘못 쓸 경우 이상한 오류 발생함. 아직 데이터 바인딩에 대한 오류 지원은 미흡함으로 주의해야 함.

Two-way Binding

  • Binding : UI <- Model
  • InverseBinding : UI -> Model
  • Two-way Binding : 둘다
public class MainActivity {
    public void onClickDone() {
        binding.getModel().text.set("이렇게 초기화가 됩니다.");
    }
}
public class TwowayBindingModel {
    public final ObservableField<String> text = new ObservalbeField<>("");
}
<layout>
    <data>
        <variable
                  name="activity"
                  type="com.test.blabla.MainActivity" />
        <variable
                  name="model"
                  type="com.test.blabla.TwowayBindingModel" />
    </data>
    <LinearLayout
                  ... >
        <Button android:onClick="@{()->activity.onClickDone()}" />
        <EditText
                  android:text="@={model.text}" />
        <TextView
                  android:text="@{model.text}" />
    </LinearLayout>
</layout>

양방향 바인딩 : @={model.title}

단방향 바인딩 : @{model.title}

EditText는 양방향 바인딩이라 텍스트 수정시 InverseBinding이 이루어지며, 이 후 변경된 값으로 Binding이 이루어짐.

  • Binding

    @BindingAdapter("android:text")
    public static void setText(TextView textView, String text) {
        tetView.setText(text)
    }
  • InverseBinding

    @InverseBindingAdapter(attribute={"android:text"})
    public static String getText(TextView textView) {
        return tetView.getText().toString();
    }

InverseBinding 선언부

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface InverseBindingAdapter {
    String attribute();
    String event() default "";
}

InverseBinding에서 event 사용시

@InverseBindingAdapter(attribute={"android:text", event="textEvent"})
public static String getText(TextView textView) {
    return tetView.getText().toString();
}

@BindingAdapter("textEvent")
public static void setTextEvent(TextView textView, final InverseBindingListener listener) {
    textView.addTextChangedListener(new TextWatcher() {
        @Overrride
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            listener.onChange();
        }
    });
}

위 구현의 동작 흐름

  1. EditText에 텍스트 변경
  2. @BindingAdapter("textEvent")에서 텍스트 변경으로 InverseBindingListener의 onChange() 호출
  3. @InverseBindingAdapter(attribute={"android:text", event="textEvent"}) 에서 변경된 텍스트 반환
  4. TwowayBindingModel의 ObservableField인 text에서 값이 변경됨을 알림.
  5. @BindingAdapter("android:text") 으로 EditText와 TextView에 변경된 값을 설정함.

하지만 위와 같이 처리시 5번에서 다시 1번이 발생하게 되어 계속 반복하게 됨.

구글에서 이에 대한 직접 로직을 추가하여 막아야 한다고 함. (TextViewBindingAdpater 참조)

TextViewBindingAdpater 에서는 이전과 변경되는 텍스트 값을 비교하여 예외처리를 추가함.

<include>와 <ViewStub>

네이버 프리즘라이브의 경우 Activity가 pause 되면 안되는 상태로 설계가 되었고, 하나의 Activity에 많은 View를 추가하는 형태임.

  • 수많은 View들
  • 개발자들 사이의 분할(분담)
  • 기능들의 확장성
  • 변경의 용이성

(architecture나 패턴에 대한 부분은 제외하고 DataBinding과 View 관점에서만 논하기로 함)

main.xml -> include1.xml

​ -> viewstub1.xml

​ -> viewstub2.xml

메인에서 하위로 데이터를 전달해야 하므로 데이터도 동일하게 뎁스를 만들어서 사용함.

MainBindingModel -> IncludeBindingModel

xml에서 하위로 모델 넘길 경우

<!-- main.xml -->
<layout>
    <data>
        <variable
                  name="model"
                  type="MainBindingModel" />
    </data>
    <include
             layout="..."
             app:mode2="@{model.includeModel}" />
</layout>
<!-- main.xml -->
<layout>
    <data>
        <variable
                  name="model2"
                  type="IncludeBindingModel" />
    </data>
    <TextView
             app:mode2="@{model2.title}" />
</layout>

프리즘은 각 View별로 ViewModel 1:1 매핑하여 개발함.

ViewStub 바인딩시 include보다 까다로움.

ViewStub도 View 상속하다보니 일반적인 BindingAdapter를 사용가능하나,

ViewStub 특성을 살리는 부분은 ViewStub를 파라미터로 받는 BindingAdpater로 구현해야 함.

하지만 이는 Gradle 3.1.0이상부터 되는 것으로 보여 그 이하의 환경에서는 편법을 써야 함.

ViewStub를 DataBinding시에 ***Binding.java에는 ViewStubProxy가 사용됨.

그 ViewStubProxy 안에 ViewStub이 있음.

ViewStub을 사용시에는 반드시 android:id 가 있어야 함. (없을 경우 에러로그가 딱히 안나옴)

최초에는 inflate 필요함. ViewStub의 경우 ViewStubProxy에서 inflat시에 다시 바인딩(rebinding)을 하게 함.

위의 이유로 애니메이션 동작 등이 오동작할 수 있음.

다시 바인딩되는 범위는 ViewStub을 싸고 있는 부모뷰까지이므로 편법으로 ViewStub을 include로 싸면 되긴 함.

(대신 아름답지는 않음)

Q&A

Q. 협업을 위해 바인딩 어답터 오버로딩한다고 하셨는데, 바인딩어답터에서 바인딩어답터를 호출할 수 있습니까?

넵! 이미 BindingAdapter로 넘어오면 그 시점부터는 Java Method라고 보셔도 무방합니다. 즉… 필요한 BindingAdapter의 Method를 호출해주면 됩니다..!

Q. 바인딩 문법 틀렸을때 자바처럼 잘 디버깅해주지않던데 쉽게 문법오류 잡는 팁 있을까요?

안타깝게도… 이건 좋은 방법이 있진 않아요. 좋은 방법이라면… 수없이 많이 맞아보는 것…?ㅎㅎ…

Q. 동적으로 ui위치를 변경하고자할때 데이터바인딩을 사용하고 싶은데 뷰의 속성변경 말고 뷰 객체 자체를 받을 수 있나요?

결론적으로… 저라면 동적으로 UI위치를 변경하고자 한다면 예를들면 이렇게 작성할 것 같아요..

@BindingAdapter](https://github.com/BindingAdapter)( {"positionX", "positionY"} ) public static void moveView(View view, float positionX, positionY) { view.setTranslationX(positionX); view.setTranslationY(positionY); }

Q. recyclerView의 스크롤 이벤트 같은것도 데이터 바인딩으로 받을 수 있을까요? (스크롤 위치에 따라서 이벤트 처리를 하고 싶은 경우에)

해보지는 않았는데요. Listener를 Setting해서 값을 가져오는 방식이라면 가능합니다. InverseBindingAdapter를 이용하면 될것 같은데요.

참고로 저의 경우에는 ViewPager의 Page 이동과 offset 이동도 InverseBinding으로 처리하고 있습니다.

Q. 데이터바인딩을 사용하게 되면서 코드 가독성이 떨어진 점은 없었나요? Textview.setText면 충분하지 않았나 싶은 생각도 들고 그러는데 데이터바인딩의 장점이 궁금합니다.

이건 취향차이기인 해요. 저는 오히려 코드 가독성이 올라가는 부분도 있다라고 생각합니다. View에 대한 로직은 모두 xml에서 볼 수 있다라고 생각할 수 있으니까요. 로직이 복잡해지면 xml도, 코드에서도 복잡하긴 한건 매한가지 이긴 하니까…?

사실. 이 DataBinding은 코드의 가독성을 높인다. 개발 생산성을 높인다.의 이야기와는 맞진 않다고 생각합니다. 정확하게는 Java/코틀린 코드에서 View에 대한 참조를 제거하는 도구이다. 라고 보시는 쪽이 맞긴 해요. 또한… 이런저런 장점들이 있기는 한데… 가장 크게 예를 들면 Image Loading 같은 경우에요. 그냥 코드로 작성하게 되는경우 Image를 Load하는 모든 지점에서 자바/코틀린으로 Loading 로직을 작성해주셔야 하는데 Binding을 이용한다면 이런식으로 작성하면 끝! 할수도 있거든요

막상 열심히 써보면 편해요. 굉장히 편합니다. View를 사용할 때 thread 걱정도 사라지고요. 얘가 NullPointer도 잡아주고요… 내 손으로 작성하는 코드의 양을 줄여서 실수를 줄여주는 부분도 있습니다. 이제 저는… Binding 없이는 코딩이 좀 어렵다. 생각이 들 정도로 적어도 제게는 정말 편리한 도구입니다



앱쇼 코리아 2018

행사 정보

  • URL : http://app-show.co.kr/
  • 행사명 : 제5회 앱쇼코리아 / The 5th AppShow Korea
  • 주제 : 콘텐츠, Ai · IoT · VR/AR · 빅데이터 · 블록체인과 연결되다
  • 기간 : 2018년 12월 20일(목) ~ 12월 22일(토), 3일간
  • 장소 : Coex Hall B1 (지하 1층 아님)

참가 업체

부스번호업체전시품목홈페이지
A01그린휠㈜전기자전거, 접이식전기자전거, 미니벨로전기자전거, 전기자전거 키트www.greenwheel.kr
A02헤드블락블록체인 활용한 채용 no-show 해결www.headblock.io
A03알파콘 네트워크 파운데이션유전자검사키트, 맞춤영양제 등www.alphacon.io/
A04에스크락투자자 리스크를 최소화한 ICO 참여 금융 모델www.esc-lock.com
A05한국M&A센터선순환 투자구조 마련을 위한 M&A/투자유치 전문 플랫폼 회사www.mnacenter.com
A06(주)히즈윌컴즈블록체인 마케팅 홍보www.coinistar.com
A07주식회사 엘라마체인앱/웹 기반 암호화폐 결제 플랫폼(ELA PAY)www.elamachain.io
A08주식회사 브리지REMOFIT
A09㈜크립토레드인터내셔널Coin Monster, Nix paywww.nixblock.com
A10㈜제미타스마트 펀칭 게임기www.zemita.com
A11주식회사 락인컴퍼니LIAPP(Mobile App Protector)www.lockincomp.com
A12주식회사 블루디지털사이니지, 광고 메뉴보드, 키오스크, 안드로이드 동영상 재생기www.signmall.kr
A13주식회사 이브이스마트 헬스 자판기
A14(주)아이씨쥐LED 전광판 전시차량, LED 전시작품www.trinled.com
B01성균관대학교 산학협력단영상정보를 이용한 건강 측정(스트레스, 혈량, 우울증, 호흡, 혈액점도, 맥박, 체온)www.skku.edu
B02크레아트봇㈜허밍버드 로봇 키트(허밍버드 듀오, 허밍버드 비트, 핀치로봇)http://www.creartbot.com/
B03(주)엉클샘산타클로스365http://santa365.unclessam.com/
B04엑스오자가충전 IoT 위치추적기www.xoco.kr
B05케이디자인미디어AR스티커https://kdm.pe.kr
B06(주)휴네이처IoT App, IoT 무선모듈www.hunature.net
B07주식회사 솔투온교육용 클라우드 시스템 - 스터디 버튼www.soul2on.com
B08스토리앤브라더스㈜성향분석 기반 AI 매칭 팀빌딩 플랫폼, "사피언스"https://sapiensteam.com
B09토비테크놀로지코리아 주식회사시선추적(Eye tracking) 솔루션www.tobiipro.com/ko/
B10주식회사 뮬리즈뮬리즈(Muilyzz)https://www.muilyzz.com
B11스마트드림3초만에 숨어있는 핸드폰 찾기! 스마트버튼 'PopPop'www.poppopbutton.com
B12(사)한국스마트융합산업협회콘텐츠 디자인 기반 융합형 실무인력 양성 아카데미 교육생 포트폴리오 / 회원사 보유 제품 및 서비스http://kscia.kr
B13(주)트랜스박스TransBox App, API 등www.transbox.xyz
B14디사인Display + VMV contens creation Solution
B15미래야 놀자엑스 토네이도, 엑스 팡팡www.barovr.com
B16(주)쓰리디뱅크3D 리얼플러스, IoT 3D 홀로그램www.3dbank.xyz
B17주식회사 글로핸즈전자계약 시스템https://www.glosign.co.kr/index
B18페이게이트세이퍼트 블록체인 멀티시그 월렛http://www.paygate.net
B19주식회사 태명월팜www.prb.co.kr
B20㈜위닝아이비접촉 모바일 생체(지문, 장문) 인식 솔루션www.winningi.com
B21화민테크3초세이프티(자동차용 2차사고방지, LED 튜브안전표시판)www.fwamin.com
C01코너스톤 비지진 및 재난 관련 안부확인 시스템(Safetylink24)www.cornerstone-b.com
C02일본 IT 솔루션 비즈니스 매칭
C03세종학당재단한국어 모바일 학습 앱(세종한국어 어휘/세종한국어 문법/세종한국어 회화, 발음)https://www.ksif.or.kr/index.do
C04(재)한국과학창의재단사이언스레벨업 콘텐츠(가상현실 및 증강현실 기반의 실감체험형 교육콘텐츠 앱)https://www.kofac.re.kr
C05웹스톰NORI2APPhttp://nori2app.com/
C06에듀템하루 10분 중국어와 친해지는 시간 "보라구중국어"www.edutem.net
C07㈜삼우이머션IMMERUTION TRAINING 선박엔진 실습 VR 교구재 /VARLOS Smart Factory AR -Realwearwww.samwooim.com
C08㈜요트북스마트 마리나 플랫폼http://www.yachtbook.co.kr/
C09(주)아파트너아파트너www.aptner.com
C10㈜씨앤에스솔루션카드전표 어플리케이션http://www.cad.co.kr/cloud
C11㈜리나소프트열공시간 (APP), 열공시간 스터디 플래너www.rinasoft.co.kr
C12주식회사 비틀종이와크레파스 / 360VR체험관beetle-lab.com
C13와이즈모바일㈜위치기반 날씨앱, 오픈웨더(Open Weather) 및 주차비 아끼는 앱, 파킹박(Parking Park)www.wisemobile.co.kr
C14㈜딥비전스에어체커(Air-Checker), 미세찰칵http://deepvisions.co.kr
C15㈜알스피릿NowMoment Company – 상장기업 주가예측/외내부 영향지표 분석 콘텐츠 서비스www.rspirit.co.kr
C16유한회사 나노웨더초고해상도 기상기후 복원데이터 기술 알파멧(AlphaMet)www.nano-weather.com
C17㈜에스엠에스보안소프트웨어/패스볼트, 블랙매직, 아이세이퍼www.smsinfo.co.kr
C18페이업 주식회사블록체인 기반의 판매자를 위한 간편결제 시스템 ‘Payup 서비스’www.payup.co.kr
C19주식회사 애드잇스마트 병해충 검색 시스템http://www.additcorp.com
C20주식회사 옷딜패션중계 앱 서비스www.otdeal.io
C21(주)소프트파워SW자동화저작도구/스마트메이커www.smartmaker.com
C22주식회사 라베디자인멀티미디어 콘텐츠http://labae14.wixsite.com/labae
C23더테라피심리상담플랫폼 & 스마트미러 마인드코디thetherapy.co.kr
C24㈜씨브이티일렉트로닉스코리아Interactive White Board (터치디스플레이, 전자칠판)www.cvtelectronics.co.kr
C25공컴네트워크아두이노 DIY 피아노 키트 / 피노키트gongcom.kr
C26푸디온투어앱(Application) / 푸디온(foodieon)www.foodieontours.com
C27ViolinMusueM서비스/앱,웹.게임/그림책 - 동편제판소리 에니메이션 앱www.violinmuseum.com
C28㈜리디쉬친환경, 친에너지, 친경제적, 저탄소형 배달음식 그릇 순환 서비스www.redish.co.kr
C29클라우드포유AWS를 그려서 만들고 관리하는 VisCAtwww.cloud4u.io
C30주)제이제이기술햅틱 전자펜 & 필링펜과 함께하는 오링가 (미술 컨텐츠)www.feelingpen.com
C31인포소닉www.infosonic.net
C32㈜넷솔루션액션캠www.netsolution.kr
C33굿모닝코리아자산관리NH농협연금저축상품
D01제주특별자치도관광협회제주 지능형관광콘텐츠 (스토리플래닛, 브이디에스, 반딧불공작소, 웨이플러스, 에이투젯)www.visitjeju.or.kr
D023D 상상3D 프린터 제품 및 출력물www.3dsangsang.com
D03주식회사 한국표준장례문화원대장정 앱https://click9545.modoo.at/
D04D LABS미니드론축구경기장
D05페어네비전기시획 어플리케이션
D06㈜쓰리디코리아컬러 3D 프린터 GoodBoT 시리즈 , 필라멘트(PLA, Flexible, ABS, 향기 필라멘트 등)www.3dk.or.kr
D07이플랩㈜보행자용 증강현실 네비게이션 & O2O 마케팅www.Witchew.com
D08㈜유익소프트APP 토탈케어 서비스 '컨택'www.yooic.com
D09(주)엠카탈로그모바일 콘텐츠 디자인/반응 분석 솔루션 '메이크뷰'http://www.makevu.com
D10씨피디그룹캠지(CAM.G)www.cpdgroup.kr
D11㈜쿨투라칸차무등산애비뉴(Mudeungsan Avenue)www.MudeungsanAvenue.com
D12㈜유니컴태블릿용, 노트북용 충전보관함www.unicom.co.kr
D13아트맨미세빅(미세먼지 빅데이터) 모바일 어플리케이션www.misebig.com
D14주식회사 스타핑인공지능 모바일 이미지 검색쇼핑www.staping.co.kr
D16㈜나루애드영상배너www.naruad.com
D20㈜아이씨쥐LED 전광판 전시차량, LED 전시작품www.trinled.com
E01박스페이스랩토이와 결합한 아두이노 교육용 키트www.boxfacelab.com
E02틴소프트 주식회사온라인 수학 마춤학습 솔루션 '메타매쓰' 블록체인 기반 인공지능 능동형 교육플랫폼 '스터비'www.metamaths.com
E03틴메이저청소년을 위한 대학생 전공&입시 멘토링 플랫폼www.teenmajor.com
E04주식회사 모야커뮤니케이션분양권거래소' 아파트 분양권 정보 및 실제 매물현황을 한눈에 볼 수 있는 웹, 앱서비스를 제공www.buyhouse.co,kr
E05젠덕쇼보드(SHOWBOARD)' 부동산의 매물광고를 온오프라인 통합관리 하는 플랫폼www.genduck.com
E06쉐어멜론그저 이쁜 로고가 아닌 기업을 그대로 대변하는 브랜딩을 만들어보세요. 단 7분만 투자하시면 기업 브랜딩 컨설팅을 무료로 받아보실 수 있습니다. 전문가들의 다양한 디자인 연계 서비스도 만나 보세요.www.sharemelon.com
E07트립엔픽'"커스터마이징 로컬여행 맞춤 서비스" 트립엔픽www.tripnpick.com
E08다이어트치킨다이어트레시피&요리법와 식단을 제공하는 어플리케이션http://bit.ly/2tdyOFN
E09뷰자데GPS연동 위치기반 공간큐레이션/엔터테인먼트 모바일 앱서비스 'VUJADE(뷰자데)'https://play.google.com/store/apps/details?id=com.officialvujade.mobile&hl=ko
E10(주)콜미코펫택시 콜 중개 플랫폼 앱서비스 ‘펫츠’http://www.petts.co.kr
E11유한회사 동이AR/VR 기능을 활용하여 가상 전시를 통한 미술품 거래/대여 플랫폼 '아트가온(ARTGAON)'http://www.dongyiauction.com/
E12엘튜브특허 검색 및 동향 자동화 플랫폼http://Ltube.co.kr
E13아름다운 동행Beautiful Companion
E14주식회사 첸트랄눈 건강 VR헤드셋, VRight(브라이트)www.zentral.co.kr
E15페이리더스테이블오더' 고객이 본인의 스마트폰으로 주문/결제(더치페이) 할 수 있는 서비스 플랫폼www.tableorder.co.kr
E16주식회사 뉴코애드윈드음식과 함께 광고까지 배달하는 스마트 디디박스www.newkod.com
E17주식회사 두바여성 파트타임 일자리정보제공 어플 '이모'www.doobar.kr
E18㈜플레이브이알VR, AR 컨텐츠www.playvr.kr
E19캐링솔루션Longship360 VR Camera, Longship eNotewww.longship.kr
C34TVCC. Co. ltdTVCC 생방송 데일리 암호화폐 캐스팅 방송 ‘블록체인 투데이’ 라이브 방송 진행 블록체인 전문 미디어사 TVCC 소개 및 2019년도 방송진행 방향소개http://tvccnews.co.kr
D15XTOCKXTOCK 생태계를 유지하고 활성화하기 위한 프로토콜 소개, Global OTC Market 소개https://xtock.io/
D17Big CBIgC플랫폼 생태계 구성 및 미스터리 블록, BIGC COIN 소개http://www.bigccoin.com
D18BIEX2019년 상반기 글로벌 오프라인 거래소 론칭 레이어 발표 바이블코인 생태계 소개http://biblefintech.com/
D19Coinbit완성형 거래소 코인 DEX 상장, 강력 다중보안 메커니즘 소개https://www.coinbit.co.kr

행사장 가는 길

코엑스 홀 B1 이라고 쓰여 있어서 지하로 헷갈리기도 했습니다.

1층에 있는 B1 위치로 찾아가면 됩니다.

멀리서 바라본 행사장 입구입니다.

행사장 앞에는 부스 설명과 세미나 안내가 있고 한쪽에는 안내데스크가 있어 입장권을 받을 수 있습니다.

행사장 내부

행사장 초입부터 부스는 시작됩니다.

케이디자인미디어

AR 스티커를 활용하여 아이들 컨텐츠를 제공하는 업체였습니다.

AR 스티커가 어떻게 나오는지는 확인을 못해보았네요.

솔투온

학습용 질의응답 보조 기기로 보였습니다.

학생들이 BLE 기기로 선생님을 폰을 서버 삼아 퀴즈 답을 제출하고 그를 통해 학습률에 대한 통계 등을 지원한다고 하네요.

단 퀴즈 문제마다 답을 제출시 자기가 어떤 답을 제출한지 화면에 자기 번호가 나타나지만, 실제 맞춘 것인지에 대한 리액션은 따로 없었습니다.

선생님을 위한 통계 등의 화면에서만 확인이 가능하다고 들었던 것 같네요.

그래도 아이들의 적극적인 참여를 유도할 수 있는 서비스 같았습니다.

토비테크놀로지코리아

아이트래킹을 제공해주는 업체 부스였습니다.

사용자의 시선을 측정하여 데이터를 제공하는 것으로 보였습니다.

착용형과 설치형으로 아이트래킹이 가능하다고 하였습니다.

착용형은 마네킹의 안경이나 VR 기기 등으로 가능하였고, 설치형은 모니터 아래 카메라 등으로 측정이 가능하다고 하더군요.

흥미가는 아이템이나 실제 어떤 서비스에서 어떻게 활용될지는 궁금한 부분이었습니다.

실제 사용 중인 업체들로 코카콜라나 기타 큰 업체들을 설명해주셨으나, 정확히 어떤 사례에서 쓰이는지는 추가 설명을 듣진 못하였습니다.

스마트드림

폰을 찾기 위한 간단한 아이디어용 제품이었습니다.

폰이 어디있는지 모를 때 버튼을 누를 경우 폰에 설치된 앱에서 화면 및 소리로 알림을 주는 형태였습니다.

역시 BLE를 사용한 기술로 추가 기능들이 필요하지 않을까 싶은 서비스였습니다.

REMOFIT

골프 교정용 서비스 같았습니다.

간단히 시연 영상 등을 보았을 때 스윙 각도, 속도 등 여러 정보를 제공하는 것으로 보였습니다.

실제 어떻게 사용자의 스윙 등을 측정하는지는 살펴보지 못했네요.

제미타

나름 재미있어 보이는 체험형 게임이었습니다.

일반 게임의 버튼들을 운동기구 처럼 구성하여 게임 컨트롤을 위해 움직이게 만드는 서비스였습니다.

타격감도 확실히 느낄 수는 있고 맞춰서 게임 컨텐츠도 잘 준비된 느낌이었습니다.

다만 개인들이 하기엔 덩치들이 큰 장비들이고, 아이들 운동용으로 학원 등에서 활용하기엔 좋아 보였습니다.

미래야놀자

이런 전시장의 이젠 단골소재가 된 VR 기반 체험형 게임으로 보였습니다.

점심시간인지라 부스에 사람이 없어 체험은 못했네요.

아마 이번 전시장에선 그나마 인기 좀 끌 부스 같았습니다.

글로싸인

모든 계약을 전자 계약서로 만들고 보관 및 관리를 해주는 서비스였습니다.

블록체인 기술을 접목하여 관리를 해주며, 근로계약서나 일반 임대차 계약서 등의 개인 서비스 및 B2B용 계약서 등을 위한 회사용 서비스 등이 있어보였습니다.

향후 앱으로도 지원 예정이라네요.

역시나 블록체인

블록체인 기반 서비스도 한쪽 면을 가득 채울 정도로 많았습니다.

개인적으로 관심이 없는 쪽이라 자세히는 못봤지만, 게임형태도 있고 다양한 접목 사례들을 들고 나온 듯 했네요.

화민테크

앱과는 어떤 연관이 있는지는 모르겠지만, 자동차 사고시 표식 기능을 하는 장비도 있었습니다.

기존 고장난 차량 뒤에 적당한 거리를 두고 삼각대를 설치해야 되는데, 이건 차 위에 올리기만 하면 된다네요.

사용시에만 저 위험한 풍선이 튀어나온답니다.

아이씨쥐

이렇게 대형 LED 제품들을 전시해 놓은 부스도 있었습니다.

다양하고 부스가 거대하였죠.

빠질수 없는 드론

이렇게 미니 드론도 판매 중입니다.

특가라고 하지만... 저는 잘 모릅니다..

위닝아이

손바닥으로 인증을 해주는 서비스였습니다.

어떤 방식인지 궁금하였지만, 아쉽게도 점심시간이라 부스에 아무도 없었네요.

고객사 라인업으로 봐서 어느정도 상용화도 진행 중인 서비스 같네요.

인포소닉

비가청 음파를 이용한 데이터 전송 기술인 소닉 코드를 개발한 곳이라고 하네요.

안내 문구에 QR과 바코드를 대체할 서비스처럼 쓰여있긴 하였는데요.

실제로는 좀더 조심스럽게 써야하는 서비스들에 필요한 기술 같았습니다.

QR이나 바코드처럼 접근성이 좋은 것은 아니지만 1:N 통신 등에서는 유리한 점들도 많아 보였습니다.

실제 이 기술을 활용하기 위한 접근들이 이루어지고 있다고 하니 조만간 실제 활용한 서비스들도 볼 수 있지 않을까 싶었습니다.

레디쉬

나름 참신한 서비스 같은 부스였습니다.

배달 그릇을 수거 및 세척 등의 관리를 해주는 서비스였습니다.

최근 대두되는 환경 문제 등의 주제 의식과 우리나라에서 흔한 배달 서비스의 수거비용에 대한 걱정을 파고든 서비스 같네요.

공컴네트워크

아두이노를 활용한 DIY 피아노 키트로 코딩 교육을 진행하는 서비스였습니다.

현재 유료 커리큘럼으로는 파이썬 및 스크레치 등을 진행하고 있다네요.

스토리앤브라더스

AI 를 통한 팀 매칭 서비스 및 커뮤니케이션, 프로젝트 관리 등을 지원하는 서비스입니다.

스타트업이나 신규 팀 셋업이 필요한 쪽에서 한번 고려해볼만 한 서비스였습니다.

크레아트봇

허밍버드? 라는 보드와 모터 등을 이용해 DIY 장난감 등을 만들 수 있는 서비스였습니다.

스크레치 등을 통해 프로그래밍 교육을 하는 것으로 보였습니다.

아파트너

아파트 앱에서도 부스에 나오셨네요.

아파트 관련 관리 및 커뮤니케이션 지원 등을 제공하는 것 같네요.

요트북

전시장에 여행 관련 서비스들도 꽤 있었는데요.

그 중 하나였던 요트를 타고 여행하는 서비스였습니다.

특이해보여서 찍어봤네요.

와이즈모바일

파킹박이라는 주차장 중계 서비스였습니다.

주차장에는 관리시스템 및 차단기 기기 등을 통해 고객 유치 및 출입 제어를 제공하였고,

(차단기는 옵션인 듯 했습니다.)

사용자에게는 미리 주차장 일일권 등을 선결제 후 사용이 가능하게 하는 서비스였습니다.

대략 서울경기 등에 300여곳의 제휴를 맺고 있고, 강남에도 많은 곳과 제휴 중이라네요.

리나소프트

공부도 관리해주는 스터디 플래너 서비스입니다.

시간 관리 등을 제공하는 것 같네요.

딥비전스

딥러닝과 이미지 프로세싱 기반으로 미세먼지 측정 솔루션을 제공하는 부스였습니다.

장비들도 있고 사용 시나리오가 궁금했지만... 역시 점심시간인지라.....

유익소프트

앱호스팅 서비스라고 하는데요.

실제 앱을 호스팅 하는 건 아니고 앱을 템플릿화 하여 그에 맞춰 제작 및 서버 호스팅을 제공하는 거 같았습니다.

앱을 실제 앱스토어에 올리거나 관리는 직접 해야된다는 것 같네요.

영세한 자영업 쪽의 수요가 있을지 궁금한 서비스였습니다.

더테라피

심리상담플랫폼이라는데요.

그림치료 같은 것들도 준비해 두신것 같고....

뭔가 중요한 작업 중이신 것 같아 자세히 못 물어봤네요.

푸디온투어

또 하나의 여행 서비스였습니다.

여행시 해당 지역의 집밥? 가정식? 등을 연결해주는 서비스 같았습니다.

요식업 식당들이 아니라 가정집을 연결해 주는 것으로 보이는데요.

서비스가 런칭된다면 향후 관리가 참 중요할 서비스 같았습니다.

BIEX

좀 특이한 컨셉의 블록체인 부스였습니다.

부스 설명에는 바이블코인 생태계를 소개한다고 하는데요.

기독교 기반 금융 서비스 같네요. 종교 기반의 서비스 부스는 처음 접해본 것 같네요.

캐링솔루션

전자노트를 전시하고 있어 구경했습니다.

일반적인 스크린이 아니라 전력소모가 적고 감압식으로 노트가 가능한 제품이었습니다.

대신 저장이 불가하여 폰에 캠스캐너 등의 앱을 깔아 캡쳐하여 저장을 대신하다고 하네요.

간단한 메모 용으로는 괜찮아 보였습니다.

뉴코드애드윈드

배달 오토바이 박스에 광고를 유치할 수 있는 제품입니다.

3 면에 모니터와 스피커를 통해 영상 및 음성 광고를 지원하는 듯 했습니다.

실제 상용화에는 내구성 등이 문제가 되지 않을까 싶네요.

페이리더스

식당 등에서 손님들의 폰을 통한 직접 주문이 가능한 앱 서비스입니다.

식당 측에는 관리 시스템을 지원해 주문 관리가 가능한 것으로 보이네요.

기존 서비스들이 있는 것으로 아는데요. 앱을 퍼트리는 것이 관건이 될 것 같네요.

콜미코

펫츠라는 반려동물 택시 중계 서비스입니다.

반려동물 계의 카카오 택시를 노리는 서비스 같네요.

트립엔픽

맞춤형 여행 서비스입니다.

여러 옵션 등을 통해 자신에게 맞는 현지 여행 일정을 잡아주는 서비스 같았습니다.

후기

작년도 그랬고, 올해도 기술에 대한 부분보다는 다른 곳에서는 어떤 비즈니스를 먹거리로 보고 있나라는 참고를 할 수 있는 행사였던 것 같습니다.

다소 아쉬운 점도 많지만 그래도 앱을 통한 서비스를 하는 사람들이라면 한번 구경해볼만 한 것 같네요.

사전 예약의 경우 무료이니, 코엑스 근처에 갈 일이 있다면 부담없이 둘러 볼 수가 있을 것 같습니다.

Google for Mobile I/O RECAP 2018 (10)

10. AI & Cloud. 모바일 개발자를 위한 ML Kit: Machine Learning SDK 소개

  • 발표자 : 신정규 (Founder & CEO, Lablup Inc.)
  • 세션설명 : 모바일 개발자를 위해 더 쉬워진 머신 러닝! Firebase에서 사용 가능한 머신 러닝 SDK, ML Kit가 발표되었습니다. ML Kit을 사용하면 Android와 iOS 모든 플랫폼에서 강력한 머신 러닝 기능을 앱에 적용할 수 있습니다. 초보자도 쉽게 시작할 수 있는 ML Kit을 국내 머신 러닝 전문가, Google GDE인 Lablup Inc.의 신정규 대표가 소개합니다.

TensorFlow

TensorFlow <--> TensorFlow Lite <--> TensorFlow.js

TensorFlow 모델을 가져다 쓰는 애플리케이션 영역이 필요한 시점임.

ML Kit

참고 : https://developers.google.com/ml-kit/

양질의 데이터 부족, 모바일 기기에 맞는 모델이 필요함.

위 이유로 ML, Deep Learning 도입이 어려움.

그래서 ML Kit이 등장하게 됨.

기본 API

  • 이미지 라벨링 : 개체, 위치, 활동, 동물 종, 제품 등을 식별
  • 텍스트 인식 (OCR) : 이미지에서 텍스트 인식 및 추출
  • 얼굴 인식 : 얼굴 및 얼굴 표식 감지
  • 바코드 스캐닝 : 바코드 스캔 및 처리
  • 랜드마크 인식 : 이미지에서 인기있는 랜드 마크 식별
  • 스마트 답장 (coming soon) : 문맥에 맞는 문구 제안

이미지 라벨링, 텍스트 인식, 얼굴인식, 바코드 스캔은 디바이스에서도 직접 사용 가능함.

Custom Model & Cloud Deploy

맞춤형 모델을 지원하고 Cloud 사용하여 배포 가능

디바이스/Cloud API 사용은 거의 동일함.

이미지 라벨의 경우 디바이스 API는 무료, Cloud API는 사용 제한이 있고 정확도는 더 높음.

Q&A

Q : 기본 API 사용은 그냥 가능한가?

A : 요금제 Blaze 이상이면 일부 무료사용이 가능함. (월 1000건까지 무료)

참고 : https://firebase.google.com/pricing/?hl=ko

https://cloud.google.com/vision/?hl=ko#cloud-vision-api-pricing

Google for Mobile I/O RECAP 2018 (09)

09. AI & Cloud. 모바일 개발자를 위한 TensorFlow Lite 소개

  • 발표자 : Kaz Sato (Staff Developer Advocate, Cloud Platform, Google)
  • 세션설명 : TensorFlow Lite는 모바일과 임베디드 디바이스에 최적화된 머신러닝 프레임워크로, 낮은 지연시간과 작은 바이너리 크기로 디바이스 상에서의 머신러닝 추론이 가능하며 안드로이드 신경망 API를 사용한 하드웨어 가속화도 지원합니다. TensorFlow Lite를 통해 최신 AI 기술을 모바일에 적용하는 법을 알아보세요.

TensorFlow

참고 : https://www.tensorflow.org/get_started/

AI, ML, Neural Networks

최근의 AI 서비스는 모바일에서 1차 가공된 데이터를 추출해 서버에 보내 처리함.

모바일에서 이미지 처리시 클라이언트에서 이미지 라벨을 서버로 보내 처리함. 모션 캡쳐의 경우도.

TensorFlow는 Open Source S/W임.

모바일에서도 모델 학습이 가능하나 느려서 GPU가 필요함.

TensorFlow 모델을 모바일에서 사용 가능함.

모바일에서 Machine Learning 의 문제 : Memory, CPU Power, Battery 등

모바일에서 TensorFlow 사용시 처리

  • Freeze Graph : 변수를 상수화
  • Quantization : 32bit float -> 8bit int
  • Compression the Binary with Selective Registration : 12MB -> 1.5MB (for Inception v3)

TensorFlow Lite

참고 : https://www.tensorflow.org/mobile/tflite/

TensorFlow Lite의 빠르고 작은 설계

TensorFlow Lite의 core interpreter는 75KB 크기임. (TensorFlow의 경우 1.1MB)

TensorFlow Lite & ML Kit

참고 : https://developers.google.com/ml-kit/

ML Kit의 Base API 사용이 편함.

use case에 따라 custom models 사용함. (TensorFlow Lite)

TensorFlow Lite Development Flow

참고 : https://www.tensorflow.org/versions/master/mobile/tflite/devguide

Get a model -> Convert -> write ops -> write app

한계점으로는 추론 연산에만 집중되는 문제와 현재 inference 제한있음. (최대 50개의 operators 제공)

적용 사례

참고 :

https://developers-kr.googleblog.com/2017/12/on-device-conversational-modeling-with-tensorflow-lite.htmlhttps://developers-kr.googleblog.com/2017/10/how-machine-learning-with-tensorflow-enabled-mobile-proof-of-purchase-at-coca-cola.html?refer=gaerae.com

Google Assistant, Android Wear의 Smart Reply 기능에 적용. 코카콜라 앱 병뚜껑 번호 인식에도 적용됨.

TensorFlow Lite는 이미 Production App에 적용되고 있음.

Q&A

Q : TensorFlow Lite가 PC에서도 되나?

A : 리눅스라면 됨. Android IOT나 라즈베리파이도 됨.

Google for Mobile I/O RECAP 2018 (08)

08. AI & Cloud. Dialogflow와 ML API를 활용한 챗봇 개발

  • 발표자 : 정명훈 (Customer Engineer, Google Cloud)
  • 세션설명 : 빠르고 효율적으로 구축이 가능하면서도 똑똑한 챗봇을 개발하고 싶다면 꼭 주목해야 할 기술, Dialogflow를 소개합니다! Dialogflow의 강력하고 손쉬운 기능과 머신러닝 API를 사용하여 매력적인 챗봇을 개발하는 방법을 알아보세요.

메신저 사용률이 SNS를 추월함.

참고 : http://www.kinews.net/news/articleView.html?idxno=71223

스마트 디바이스 증가와 대기업들의 참여도 증가로 챗봇 급성장.

참고 : http://gobooki.net/archives/1324

주요 사용 사례 :

  • Customer support
  • Transactions
  • Getting things done

영단어 암기 프로그램

구성 : Chatbot + ML API + Google Assistant

Dialogflow

참고 : https://dialogflow.com/docs/getting-started

Dialogflow에 Topic에 대한 샘플 문장들 입력

규칙기반은 규칙에 대한 모든 정보 입력 필요. (사실상 불가능)

머신러닝 신경망에서 시맨틱 구문 분석으로 학습할 경우 규칙기반 대비 40% 정도 정확도 높음.

Google ML API

참고 : https://cloud.google.com/products/machine-learning/

ML on Google Cloud

  • Translate API : 데이터가 많아 성능이 높음.
  • Natural Language API : 자연어 처리
  • Speech API : 음성인식, 구문힌트나 인식모드로 정확도 향상
  • Vision API : 사진분석, 텍스트 인식
  • Video Intelligence API : 비디오 분석 기술

Q&A

시간 관계상 생략

Google for Mobile I/O RECAP 2018 (07)

07. Developer. Kotlin으로 코딩 시작하기

  • 발표자 : Hadi Hariri (VP of Developer Advocacy, Jetbrains)
  • 세션설명 : 한 번도 사용해보지 않은 개발자는 있어도, 한 번만 사용해 본 개발자는 없다! 사용해본 개발자의 95%가 높은 만족도를 보였다는 Kotlin! 작년 안드로이드 공식 언어로 채택된 이후 매년 빠르게 성장하고 있는 Kotlin을 시작해보세요. Google I/O에서 Kotlin을 발표했던 Jetbrain의 Hadi Hariri가 한국 개발자를 위해 직접 소개합니다.

코틀린 지식이 없는 상태에서 단편적인 키워드들로 정리한 세션이라 샘플코드 등 임의로 넣은 부분이 많습니다.

Kotlin 시작시 Android Studio의 Java to Kotlin 메뉴에 의존하지 말 것.

Property & Field

Kotlin은 필드는 없고 프로퍼티만 사용함.

참고 : https://kotlinlang.org/docs/reference/properties.html#backing-fields

Fields cannot be declared directly in Kotlin classes.

  • field: A data member of a class. Unless specified otherwise, a field is not static. - 클래스의 데이터 멤버. 특별히 언급되지 않았다면 field는 정적이지 않다.
  • property: Characteristics of an object that users can set, such as the color of a window - 윈도우의 색과 같이, 사용자가 설정할 수 있는 객체의 특성

Delegated Properties

참고 : https://kotlinlang.org/docs/reference/delegated-properties.html

  • lazy properties : 첫 번째 액세스시에만 값이 계산되어 저장됨.

    val lazyValue: String by lazy {
        println("computed!")
        "Hello"
    }
    
    fun main(args: Array<String>) {
        println(lazyValue)
        println(lazyValue)
    }
    This example prints:
    
    computed!
    Hello
    Hello
  • observable properties : 리스너는 속성 변경에 대해 알림을 받음.

    import kotlin.properties.Delegates
    
    class User {
        var name: String by Delegates.observable("<no name>") {
            prop, old, new ->
            println("$old -> $new")
        }
    }
    
    fun main(args: Array<String>) {
        val user = User()
        user.name = "first"
        user.name = "second"
    }
    This example prints:
    
    <no name> -> first
    first -> second
  • 맵에 여러 필드를 대신해 프로퍼티를 저장함.

    class User(val map: Map<String, Any?>) {
        val name: String by map
        val age: Int     by map
    }
    ...
    val user = User(mapOf(
        "name" to "John Doe",
        "age"  to 25
    ))
    ...
    println(user.name) // Prints "John Doe"
    println(user.age)  // Prints 25

Standard Library (Built-in)

lazy, vetoable 등 제공함.

funtion expression

참고 : https://kotlinlang.org/docs/reference/basic-syntax.html#defining-functions

// basic
fun sum(a: Int, b: Int): Int {
    return a + b
}

// expression
fun sum(a: Int, b: Int) = a + b

when expression

참고 : https://kotlinlang.org/docs/reference/basic-syntax.html#using-when-expression

https://kotlinlang.org/docs/reference/control-flow.html#when-expression

fun describe(obj: Any): String =
when (obj) {
    1          -> "One"
    "Hello"    -> "Greeting"
    is Long    -> "Long"
    !is String -> "Not a string"
    else       -> "Unknown"
}

exception expression

참고 : https://kotlinlang.org/docs/reference/exceptions.html

// basic
try {
    // some code
}
catch (e: SomeException) {
    // handler
}
finally {
    // optional finally block
}

// expression
val a: Int? = try { parseInt(input) } catch (e: NumberFormatException) { null }

Elvis operator

참고 : https://kotlinlang.org/docs/reference/null-safety.html

// basic
val l: Int = if (b != null) b.length else -1

// Elvis operator
val l = b?.length ?: -1

// Elvis operator (Exception)
val name = node.getName() ?: throw IllegalArgumentException("name expected")

Collections

sortWith

참고 : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sort-with.html?q=sortwithc&p=0

data class Product(val name: String, val price: Double /*USD*/)
...
fun main(args : Array<String>){
	val products = arrayOf(Product("iPhone 8 Plus 64G", 850.00),
							Product("iPhone 8 Plus 256G", 1100.00),
							Product("Apple iPod touch 16GB", 246.00),
							Product("Apple iPod Nano 16GB", 234.75),
							Product("iPad Pro 9.7-inch 32 GB", 474.98),
							Product("iPad Pro 9.7-inch 128G", 574.99),
							Product("Apple 42mm Smart Watch", 284.93))
		
	products.sortWith(object: Comparator<Product>{
								override fun compare(p1: Product, p2: Product): Int = when {
													p1.price > p2.price -> 1
													p1.price == p2.price -> 0
													else -> -1
												}
					  })
}

map

참고 : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html

var strCustList = customerList.map { it -> if(it!=null) "${it.name} lives at street ${it.address.street}" else null }
strCustList.forEach{println(it)}

mapNotNull

참고 : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-not-null.html

publicp  inline fun <T, R : Any> Iterable<T>.mapNotNull(transform: (T) -> R?): List<R>

Null declare (?) 하지 말 것.

참고 : https://kotlinlang.org/docs/reference/basic-syntax.html#using-nullable-values-and-checking-for-null

Java를 위해서 만들어진 것.

In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that can not (non-null references). For example, a regular variable of type String can not hold null:

https://kotlinlang.org/docs/reference/null-safety.html

To perform a certain operation only for non-null values, you can use the safe call operator together with let:

If you have a collection of elements of a nullable type and want to filter non-null elements, you can do so by using filterNotNull:

Semicolons

참고 : http://kotlinlang.org/docs/reference/grammar.html#semicolons

Kotlin provides "semicolon inference": syntactically, subsentences (e.g., statements, declarations etc) are separated by the pseudo-token SEMI, which stands for "semicolon or newline". In most cases, there's no need for semicolons in Kotlin code.

Inline Functions

참고 : https://kotlinlang.org/docs/reference/inline-functions.html

https://blog.uzuki.live/advanced-kotlin-inline-functions-1-basic/

https://blog.uzuki.live/inline-functions-2-local-return/

고차 함수(higher-order functions) 사용시 특정 런타임에서 패널티가 부과되며, 메모리 할당과 가상 호출은 런타임 오버헤드를 초래한다고 함.

이런 종류의 오버헤드는 람다 식을 inlining 함으로써 제거될 수 있음.

람다 사용시에만 inline 사용이 가능하며 퍼포먼스 개선이 가능하다.

Local Return 문에도 사용됨.

Functional Programming

return 타입을 명시해야 함.

fun Division(a: Int, b: Int): Int {
    return DivisionVaild(result)
    //return DivisionInvaild(result)
}

fun DivisionVaild(val result: Int)
fun DivisionInvaild(val result: String)

Sealed Classes

참고 : https://kotlinlang.org/docs/reference/sealed-classes.html

Sealed Class와 서브클래스는 같은 파일에 선언되어야 함.

Sealed Class는 abstract Class임. 직접 인스턴스화 할수 없고 abstract 멤버는 가질수 있음.

non-private constructors를 가지면 안됨.

주로 when 표현식에서 유용함.

sealed class Expr {
    data class Const(val number: Double) : Expr()
    data class Sum(val e1: Expr, val e2: Expr) : Expr()
	object NotANumber : Expr()
}
fun eval(expr: Expr): Double = when(expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    NotANumber -> Double.NaN
    // the `else` clause is not required because we've covered all the cases
}

Q&A

시간 관계상 생략

Google for Mobile I/O RECAP 2018 (06)

06. Developer. 빠르고 세련된 Android 개발 - Android Jetpack & Android Studio

  • 발표자 : 김태호 (Mobile Apps Technical Specialist, Online Partnership Group, Google)

  • 세션설명 : 견고하고 현대적인 안드로이드 애플리케이션을 만드려면 어떻게 해야할까요? 세련되고 빠른 Android 앱을 만들기 위한 컴포넌트, 도구 및 지침들을 담고 있는 Android Jetpack과 Android Studio를 소개합니다.

Android Studio

Layout Inspector

참고 : https://developer.android.com/studio/debug/layout-inspector?hl=ko

Profile

참고 :

​ CPU : https://developer.android.com/studio/profile/cpu-profiler?hl=ko

​ Memory : https://developer.android.com/studio/profile/memory-profiler?hl=ko

​ Network : https://developer.android.com/studio/profile/network-profiler?hl=ko

Runtime

  • Dalvik : 앱 Size가 중요하고, Heap Fragment 등의 이슈가 있음.
  • ART : Performance 에 최적화

Language

Java, Kotlin 사용하며, 부분적인 Kotlin 개발이 가능함. Kotlin Lint 체크 지원.

Library & API

  • AbsoluteLayout : 사용하지 말 것. 강조. 또 강조. 또 또 강조.
  • LinearLayout : 간단한 경우 사용.
  • FameLayout : 역시 간단히 사용.
  • GridLayout : 권장하지 않음.
  • RelativeLayout : 사용에 대한 비용이 비쌈.
  • ConstraintLayout : 권장하며 2.0 버전 나올 예정.

AdapterView

기존 ListView, GridView는 뷰홀더 패턴 직접 작성 등 처리 복잡하고 어려움.

RecyclerView가 다양한 레이아웃을 제공하며 사용하기 좋음.

Fragment

참고 : https://developer.android.com/reference/android/app/Fragment

This class was deprecated in API level 28. Use the Support Library Fragment for consistent behavior across all devices and access to Lifecycle.

Support Library에 있는 Fragment 사용 권장

  • android.app.Fragment
  • android.support.v4.app.Fragment (권장)

Activities

가능하다면 싱글 액티비티 권장

Architecture

참고 : https://developer.android.com/topic/libraries/architecture/

기존에는 권장하는 부분이 없었음. 현재는 AAC(Android Architecture Components) 로 가이드 제공함.(필수는 아님)

Life Cycle

참고 : https://developer.android.com/topic/libraries/architecture/lifecycle

Callback 처리 등으로 액티비티나 프래그먼트가 heavy 해짐. AAC 에서 액티비티와 독립적으로 Life Cycle을 제공함.

Views and Data

참고 : https://developer.android.com/topic/libraries/architecture/viewmodel

ViewModel이 처리하며, 인스턴스만 Activity에서 관리

Data

참고 : https://developer.android.com/topic/libraries/architecture/room

Room 등에서 지원함.

Android Jetpack

참고 :

https://developer.android.com/jetpack/

https://android-developers.googleblog.com/2018/05/use-android-jetpack-to-accelerate-your.html

Guidance

Android X

참고 :

https://developer.android.com/topic/libraries/support-library/refactor

https://android-developers.googleblog.com/2018/05/hello-world-androidx.html

기존 Support Library (android.support.*)와 AAC(android.arch.*)를 AndroidX(androidx.*)로 패키지명 교체.

버전은 1.0.0으로 리셋되며 -v4, -v7 같은 네이밍 제거됨.

OldNew
android.support.**androidx.@
android.databinding.**androidx.databinding.@
android.design.**com.google.android.material.@
android.support.test.**(in a future release) androidx.test.@
android.arch.**androidx.@
android.arch.persistence.room.**androidx.room.@
android.arch.persistence.**androidx.sqlite.@

Migration to Android X

Android Studio Canary 14 버전으로 Refactor 메뉴의 Refactor to AndroidX... 메뉴로 실행

그 외

Q&A

시간 관계상 생략

Google for Mobile I/O RECAP 2018 (05)

05. Developer. 새로운 모듈 Android App Bundle로 앱 개발하기

  • 발표자 :

    Phil Adams (Senior UX Researcher) Tom Dobek (Software Engineer, Google)

  • 세션설명 : Android App Bundle은 크기가 작은 앱으로도 우수한 사용 환경을 간편하게 제공할 수 있도록 도와주는 새로운 앱 모델입니다. 앱 크기를 대폭 줄이고 Dynamic Delivery를 통해 유저들이 앱을 더 빠르게 다운로드할 수 있도록 하는 방법을 소개합니다.

참고 : https://developer.android.com/guide/app-bundle/

https://medium.com/mindorks/android-app-bundle-aab-98de6dad8ba8

https://medium.com/mindorks/android-app-bundle-part-2-bundletool-6705b50bea4c

App Bundle이 가능하게 하는 2가지 기능

  • Dynamic delivery system
  • Modular App development

.aab 내부

  • AndroidManifest.xml가 apk에서는 바이너리 형식이지만 aab에서는 프로토콜 버퍼 형식.

  • aab는 내부에 dex 폴더가 따로 있음.

  • aab의 resources.pb는 apk의 resources.arac에 해당하는 파일로 역시 프로토콜 버퍼 형식.

  • resources table, assets table은 앱의 File Targeting을 설명함.

    예) assets/<name>#<key>_#<value>/...

Dynamic Delivery 의 기본 구성요소는 Split APK 매커니즘. (Android 5.0 Lollipop 이상)

Split APK는 일반 APK와 유사하지만 Android 플랫폼은 설치된 여러 개의 분리된 APK를 하나의 앱으로 취급할 수 있음.

App Bundle을 위한 Split 기능은 아래와 같이 사용 가능함.

Split APK의 종류

Base APK

모든 APK가 액세스할 수 있는 코드와 리소스 포함하여 앱의 기본기능 제공. 앱 다운로드시 설치되는 첫 번째 APK

Configuration APKs

각 APK에는 특정 화면 밀도, CPU 아키텍처, 언어에 대한 기본 라이브러리 및 리소스를 포함. 기기가 Base APK 또는 Dynamic feature APK 다운로드시 필요한 라이브러리와 리소스만 다운로드 됨.

Dynamic feature APKs

각 APK에는 앱 설치시 필요하지 않지만 나중에 다운로드하여 설치할 수 있는 코드와 리소스가 포함되어 있음.

Average Savings

App Bundle을 통해서 평균 20% 이상의 앱 용량을 절감함.

Publishing App Bundle

App Bundle을 만든 후 signing 하여 Google Play에 업로드.

App Bundle은 기기에 APK를 배포할 수 없는 대신 하나의 빌드 아티팩트에 모든 앱의 컴파일된 코드와 리소스를 포함하는 새로운 업로드 형태임.

signing된 App Bundle을 업로드하면 Google Play는 앱의 APK를 만들고 서명한 후 Dynamic Delivery를 통해 사용자에게 제공하는 데 필요한 모든 것을 제공함.

Publishing API에서도 App Bundle 지원함.

Internal Test Track을 사용하여 테스트.

bundletool

참고 : https://github.com/google/bundletool

App Bundle 을 로컬에서 테스트할 때 사용.

  • Android App Bundle 빌드
  • APK archive 생성
  • APK 추출
  • APK 설치
  • 장치 사양 추출

SplitInstallManager

참고 : https://developer.android.com/guide/app-bundle/playcore

Q&A

Q : 사용자가 설치 후 언어 변경시 앱을 재설치해야 하나?

A : Split App만 설치하면 됨.

Q : assets 타켓팅시 불필요한 파일 포함되는데 개선 여부는?

A : 타켓팅을 상세히 해서 하면 됨.

Q : 앱 수정시 앱 번들 모두 업데이트해야 하나?

A : 그렇다.

Q : 베이스 외 모듈 배포 가능하나?

A : On Demand 버전은 따로 배포가 안됨.

Q : 앱번들을 위한 최소 버전은?

A : Pre L도 지원함으로 따로 최소 버전은 없음.

Q : 모듈화에 대해 자세한 설명이나 사례는?

A : 게임에서 레벨에 따라 별도 다운로드 제공.

Q : 앱 번들 기기 지원 관련 이슈는?

A : 현재는 없음.



Google for Mobile I/O RECAP 2018 (04)

04. Developer. Android P 최신 기능 소개

  • 발표자 : 양찬석 (Developer Advocate, Google)
  • 세션설명 : 빠르고 간결하면서도 보안성이 강화된 Android P의 새롭고 중요한 기능과 개발자가 주의해야 하는 점을 소개합니다.

구글에서는 많은 서비스에 AI 접목하는 것을 고려 중임.

  • Adaptive Battery
  • Adaptive Action
  • Slices

Adaptive Battery

참고링크 : https://developer.android.com/preview/features/power

  • 기존 : Doze, Battery Saver 등
  • P : Background Restrictions, App Standby Buckets 등

App Standby Buckets

총 4가지로 분류

  • Active : App이 현재 사용 중.
  • Working set : 앱이 정기적으로 사용 중.
  • Frequent : 앱이 자주 사용하지만 매일은 아님.
  • Rare : 앱이 자주 사용되지 않음.

Rare 의 경우 제약이 생기며, FCM 같은 기능도 등급 조정이 가능함.

예를 들어 High Priority FCM 메시지도 하향 조정이 가능함.

Background Restrictions

유저가 Background Restrictions 기능 켤 경우 Android Vitals에서 Bad behavior로 판단된 앱은 백그라운드에서 처리 가능한 기능이 거의 없음.

심지어 foreground 서비스도 안됨.

Android Vitals가 중요하며, wake lock으로 자주 디바이스를 깨우는 경우 Bad behavior로 판단될 가능성 커짐.

참고 : https://developer.android.com/topic/performance/vitals/wakelock

App Actions

디바이스 내 딥링크로 생각하면 됨. 사용자 행동 학습 후 여러 서비스에서 제공함.

Google 검색 앱, Play Store, Google 어시스턴트, 런처 등의 구글 앱이나 시간대 별 폰 wake시 등.

구글은 사용자 니즈를 알 수가 있지만 그걸 할 수 있는 앱은 알 수가 없음.

그래서 앱에서 Built-in Intents를 사용해야 함. 이는 actions.xml에 정의해야 함.

(Built-in Intents는 향후 더 늘어날 예정)

참고 : https://developers.google.com/actions/reference/built-in-intents/

NameAction IDDescription
Get fortuneactions.intent.GET_FORTUNEGet your fortune from a fortune teller
Get horoscopeactions.intent.GET_HOROSCOPEGet a horoscope by date of birth or sign
Get jokeactions.intent.GET_JOKEGet a joke about a topic or from a creative work
Get a quotationactions.intent.GET_QUOTATIONGet a quotation from a particular author or creative work
Get credit scoreactions.intent.GET_CREDIT_SCOREGet credit score from a credit agency
Get cryptocurrency pricesactions.intent.GET_CRYPTOCURRENCY_PRICEGet prices for a particular cryptocurrency
Play gameactions.intent.PLAY_GAMEPlay a game.
Check watersports conditionsactions.intent.CHECK_WATERSPORTS_CONDITIONSCheck watersports conditions at a given location
Check air qualityactions.intent.CHECK_AIR_QUALITYCheck air quality at a place
Check water conditionsactions.intent.CHECK_WATER_CONDITIONSCheck water conditions at a time or place
Start calming activityactions.intent.START_CALMING_ACTIVITYHelp user engage in a calming, meditative activity

Slices

참고 : https://developer.android.com/guide/slices/getting-started

앱 일부를 앱 외에 다른 앱 등에서 사용.

위젯이 비슷하나 위젯은 자유도가 너무 높고 범용성이 떨어졌었음.

Slices는 템플릿을 제공함. (Notification 처럼 Builder 로 구현)

action와, toggle, slider 등 제공

support 라이브러리 형태로 지원함으로 하위지원 및 최신 패치 적용 가능함.

SliceProvider 생성해야 함.

App Actions와 연결성 있게 서비스 가능할 것으로 보임.

Notification

참고 : https://developer.android.com/preview/features?hl=ko#notifications

  • Messaging Style.

  • Image 지원함.

  • SmartReply 기능 지원.

  • Notification Blocking : 사용자가 빈번히 Notification을 dismiss할 경우 시스템에서 Blocking을 제안하게 됨. 이 경우 Notification Channel 단위로 처리되므로, 앱에서 Channel 관리가 필요할 것으로 보임.

Display Cutout

참고 : https://developer.android.com/preview/features?hl=ko#cutout

시장에 지원하는 디바이스가 늘어남으로 플랫폼 차원에서 지원하게 됨.

Status Bar 높이를 하드코딩한 경우 문제가 됨. (기존은 24dp로 알려져 있지만 Cutout의 경우 약 57dp? 정도임)

기존 AppBar는 자동으로 높이 조절하므로 상관이 없으나, 풀스크린 앱이 문제가 됨.

View.OnApplyWindowInsetsListener의 WindowInsets 로 Cutout 사이즈 확인이 가능함.

Private API

참고 : https://developer.android.com/preview/restrictions-non-sdk-interfaces

비 SDK 인터페이스를 참조하거나 리플렉션 또는 JNI를 사용하려할 경우 제한 사항 적용.

ETC - Google Play Target SDK Rules

참고 : https://developer.android.com/distribute/best-practices/develop/target-sdk

ETC - Android Emulator

참고 : https://androidstudio.googleblog.com/2018/04/emulator-2727-canary.html

속도개선됨.

ETC - Chrome OS용 Android Studio

참고 : https://developer.android.com/topic/arc/studio

Q&A

Q : App Actions의 앱 우선순위는 어떻게 결정되나? (사실 질문이 기억안남)

A : 앱 순위는 AI를 통해 사용자가 가장 사용할만한 앱을 제안하게 됨.

Google for Mobile I/O RECAP 2018 (03)

03. Keynote. 모바일 개발자를 위한 I/O 2018: Android의 새로운 기능 소개

  • 발표자 :

    Sean McQuillan (Developer Advocate Android, Google) Hadi Hariri (VP of Developer Advocacy, Jetbrains) Benjamin Frenkel (Product Manager, Google)

  • 발표자료 :

    Andrioid에서 개발자들은 무엇을 더 할 수 있을까요? 개발자에게 더욱 많은 것들을 가능하게 하는 Android 플랫폼의 새롭고 흥미진진한 최신 기능을 총정리해드립니다.

Android App Bundle

App Size를 줄이는 것은 중요함. (100 MB 이상의 앱의 설치율은 30% 정도 떨어짐)

Android App Bundle을 사용하여 동적 기능 모듈(dynamic feature modules)을 앱에 추가함.

Android Studio에서 개발자가 임의의 기기에 대해 앱에 필요한 모든 것, 즉 모든 언어, 모든 기기 화면 크기, 모든 하드웨어 아키텍처가 들어 있는 App Bundle 빌드

사용자가 해당 앱을 다운로드하는 시점에 Dynamic Delivery로 사용자의 기기와 일치하는 코드와 리소스만 전달

Kotlin

Most importantly, 95% of developers tell us they are very happy with using Kotlin for their Android development. And, the more developers use it, the more that number rises. The number of Play Store apps using Kotlin grew 6x in the last year. 35% of pro developers use it, and that number is growing each month.

https://android-developers.googleblog.com/2018/05/google-io-2018-whats-new-in-android.html

Kotlin 사용자 95%가 매우 만족한다는 응답을 했으며, 프로 개발자의 35%가 Kotlin을 사용 중이라고 함.

추가로 미국, 중국, 인도 순으로 Kotlin을 많이 사용 중임.

Kotlin 사용자 절반은 다른 언어에서 넘어왔으며, 중기업 이상 20% 이상은 Kotlin으로 전환하였다고 함.

Kotlin은 Mobile, Web Backend, PC 등 다양하게 사용되고 있음.

속도 개선, 지원 툴, 언어(coroutine), 멀티플랫폼(Kotlin JVM/JS/Native) 등으로 진행 중.

Innovative distribution

App Bundle

최근의 앱들은 글로벌 서비스 지원을 위한 언어팩이나 다양한 기능 지원으로 앱 사이즈가 커지고 있음.

하지만 앱 사이즈가 커질수록 앱 설치율은 떨어짐.

이에 App Bundle로 Dynamic Delivery 지원할 예정.

Google Play Instant

게임도 모두 지원하며, 게임의 경우 비교 분석에 적합함.

게임의 경우 미니게임, 튜토리얼보다 난이도 있는 체험, 경험 못한 레벨 체험 등을 지원할 수도 있음.

Google Play, SNS, 배너 등에서도 체험 가능함.

적용 사례로는 캔디크러시와 배틀로얄 등.

지원
  • 4MB 제한 -> 10MB 제한
  • 다운로드 프로그레시브 지원
  • 유니티 라이브러리 지원 (10MB 제한과 별도로)
  • 코코스 지원 예정
  • Record -> Refactor 메뉴로 지원

Develop Faster

Android Architecture Components

Android Jetpack (하위호환 가능, 95% 기기 지원)
  • Backwards compatibility
  • Less Boilerplate
  • 등등

Android Studio 3.2 Canary

Emulator 스냅샷 지원으로 구동속도 개선 등등

Increasing Engagement

Android Slices

앱의 일부 인터페이스만 안드로이드 인터페이스 어디에든 나타나게 함.

App Actions

Google 검색 앱, Play Store, Google 어시스턴트, 런처와 같은 여러 Google 및 Android 화면에서 사용 현황과 관련성을 기준으로 App Actions가 사용자에게 표시

actions.xml에 내용 추가하면 됨.

Q&A

Q : RPG 게임에도 Instant App이 도움이 될까?

A : Yes. 사전등록, 미니게임 또는 친구추가, 길드초대 등 유저 경험을 제공할 수 있음.

Q: 인디 게임도 Instant App이 도움이 될까?

A : Yes. 인디게임에 더 필요할 듯. 무료나 프리미엄 등 모든 게임 지원함.

Q : Kotlin 사용으로 얻을 수 있는 이득은?

A : boiler pate 코드가 안 생김. 약 40% 코드 줄어듬. 효율적이고 스마트하게 행복하게 일할 수 있음. 진짜임.

Q : 안드로이드 제트팩이 코틀린과 100% 호환 가능한가?

A : 완벽히 지원함.

Q : HTML 5 에도 Instant App 지원이 가능한가?

A : Instant App의 원래 취지는 네이티브 요소를 웹의 편리함으로 가져오자는 취지였음. 취지에는 안맞을 듯.



+ Recent posts