Upload
sungju-jin
View
14.850
Download
4
Embed Size (px)
DESCRIPTION
갑을병정 산업구조에서 갑돌이의 잦은 요구사항 변경 통보를 받아보셨을 겁니다. 사람들에게 받은 스트레스를 풀려고 '그래! 난 개발자닌깐' 하고 자리에 앉아서 코드를 짜는데 반복적인 작업을 하다보면 ‘내가 이걸 왜 하고 있나’ 라는 생각까지 들기도 합니다. 안드로이드 작업을 하다보면 다음과 같은 반복적인 작업을 하는 것을 느꼈을 겁니다. 반복적인 보일러(Boiler)코드를 줄일 수 있는 오픈소스를 소개하고자 합니다.
Citation preview
반복적인 작업이 싫은 안드로이드 개발자에게
@geekbeast
진성주
발표자 소개
진성주 ( @geekbeast )
Blog : http://softwaregeeks.org
안드로이드 프로그래밍 : 제대로 된 안드로이드 앱 개발을
위한진성주 , 최종열 , 백정현 , 신중훈 ( 공저 )
http://www.hanb.co.kr/network/view.html?bi_id=981
Motivation
Motivation
Motivation
짜증나는 안드로이드 반복적인 작업
1. UI 매핑 (findViewById)
2. 파라미터 처리 (getIntent().getExtras()…)
3. 비동기처리 (Async)
4. REST 통신 ( Http )
Motivation
1. UI 매핑
TextView subject = (TextView) findViewById(R.id.subject);
TextView writer = (TextView) findViewById(R.id.writer);
TextView date = (TextView) findViewById(R.id.date);
TextView hit = (TextView) findViewById(R.id.hit);
@ViewById
TextView subject;
@ViewById
TextView write;
@ViewById
TextView date
@ViewById
TextView hit;
Motivation
2. 파라미터 처리 String id = intent.getStringExtra("id");
String name = intent.getStringExtra(“name");
String nickname = intent.getStringExtra(“nickname");
Int sex = intent.getIntExtra(“sex“,0);
Object object = intent.getExtras().get("object");
@Extra(“id") String id;
@Extra(“name") String name;
@Extra(“nickname") String nickname;
@Extra(“sex") int sex;
@Extra(“object") Object object;
3. 비동기처리 (Async) private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
Motivation
@Background
void backgroudJob() {
MovieContents movieContents = daumMovieService.getMovieContents("love");
String result = movieContents.getQuery();
setData(result);
}
@UiThread
void setData(String data) {
textView.setText(data);
}
4. REST 통신private InputStream download(String url) {
HttpURLConnection con = null;
URL url;
InputStream is=null;
try {
url = new URL(url);
con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(10000 /* milliseconds */);
con.setConnectTimeout(15000 /* milliseconds */);
con.setRequestMethod("GET");
con.setDoInput(true);
Motivation
@Rest
public interface DaumMovieService {
@Get("http://apis.daum.net/contents/movie?
apikey=DAUM_CONTENTS_DEMO_APIKEY&output=xml&q={query}")
public MovieContents getMovieContents(String query);
}
목표
반복적인 코드를 줄일 수 있는
오픈소스 (RoboGuice, AndroidAnnotations)
써보세요 ~
목차
1. Reflection, Annotation
2. 오픈소스
1. Dependency Injection Framework :
RoboGuice
2. Annotation Process Tool Library:
AndroidAnnoations
3. 오픈소스를 넘어…
4. 정리
Contents
목차
1. Reflection, Annotation
2. 오픈소스
1. Dependency Injection Framework :
RoboGuice
2. Annotation Process Tool Library:
AndroidAnnoations
3. 오픈소스를 넘어…
4. 정리
Contents
Reflection1. ( 거울 등에 비친 ) 상
2. ( 빛・열・소리 등의 ) 반사 , 반향
3. ( 상태・속성 등의 ) 반영
01Reflection, Annotation
클래스 모습을 자신이 볼 수 있고 , 수정할 수 도 있는 기술
01Reflection, Annotation
이클립스 자동완성
(Ctrl+Space)
01Reflection, Annotation
JDBC Programming…
Class.forName("oracle.jdbc.driver.OracleD
river");
Connection conn = DriverManager.getConnecti
on
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(
01Reflection, Annotation
웹 어플리케이션 web.xml<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.softwaregeeks.Servlet
</servlet-class>
</ servlet>
01Reflection, Annotation
스프링프레임워크
ApplicationContext.xml <bean id="MessageDao"
class="org.softwaregeeks.nateon.Message
Dao"/>
<bean id="NateOn"
class="org.softwaregeeks.nateon.NateOn"
>
01Reflection, Annotation
*.java *.classjavac
Java Complier
01Reflection, Annotation
*.class
Java Virtual Machine
01Reflection, Annotation
JVM Internal - http://helloworld.naver.com/index.php?vid=helloworld&document_srl=1230
01Reflection, Annotation
java.lang.relect.*
01Reflection, Annotation
클래스public class Person {
private String name;
private int age;
private Sex sex;
………
// Setter, Getter…
………
01Reflection, Annotation
클래스 필드 가져오기 Class clz = Person.class;
Field[] fields = clz.getDeclaredFields();
for(Field field : fields) {
System.out.println(field.getName());
}
01Reflection, Annotation
클래스 메소드 가져오기 Class clz = Person.class;
Method[] methods =
clz.getDeclaredMethods();
for(Method method : methods) {
System.out.println(method.getName());
}
01Reflection, Annotation
Annotation1. 주석 ( 을 달기 )
01Reflection, Annotation
01Reflection, Annotation
@Target
@Retention
public @interface 이름 {
String value();
}
만드는법
01Reflection, Annotation
package java.lang.annotation;
public enum ElementType {
TYPE, // Class, interface, or enum (but not annotation)
FIELD, // Field (including enumerated values)
METHOD, // Method (does not include constructors)
PARAMETER, // Method parameter
CONSTRUCTOR, // Constructor
LOCAL_VARIABLE, // Local variable or catch clause
ANNOTATION_TYPE, // Annotation Types (meta-annotations)
PACKAGE // Java package
}
ElementType
01Reflection, Annotation
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, // Annotation is discarded by the compiler
CLASS, // Annotation is stored in the class file, but ignored by the
VM
RUNTIME // Annotation is stored in the class file and read by the VM
}
Retention
01Reflection, Annotation
어노테이션 만들기
@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
String value();
}
01Reflection, Annotation
어노테이션 만들기public class Person {
@Description(value=" 이름이예요 .")
private String name;
@Description(value=" 나이예요 .")
private int age;
@Description(value=" 성별입니다 .")
private Sex sex;
01Reflection, Annotation
어노테이션 가져오기Class clz = Person.class;
for(Field field : fields) {
Annotation[] annotations =
field.getDeclaredAnnotations();
for(Annotation annotation : annotations) {
if( annotation instanceof Description ) {
Description description =
(Description)annotation;
System.out.println(description.value());
}
}
}
01Reflection, Annotation
@ViewById
TextView subject;
@ViewById
TextView write;
@ViewById
TextView date
@ViewById
TextView hit;
01Reflection, Annotation
01Reflection, Annotation
스크린캐스트 자료 제공http://goo.gl/EgAAU
목차
1. Reflection, Annotation
2. 오픈소스
1. Dependency Injection Framework :
RoboGuice
2. Annotation Process Tool Library:
AndroidAnnoations
3. 오픈소스를 넘어…
4. 정리
Contents
목차
1. Reflection, Annotation
2. 오픈소스
1. Dependency Injection Framework :
RoboGuice
2. Annotation Process Tool Library:
AndroidAnnoations
3. 오픈소스를 넘어…
4. 정리
Contents
02오픈소스 - Dependency Injection Framework : RoboGuice
http://code.google.com/p/roboguice/
Google Guice on Android Project!!
Google Guicea lightweight dependency injection framework
for Java 5 and above, brought to you by Google.
02오픈소스 - Dependency Injection Framework : RoboGuice
RoboGuiceGoogle Guice on Android
Project!!
오픈소스 - Dependency Injection Framework : RoboGuice02
class AndroidWay extends Activity {
TextView name;
ImageView thumbnail;
LocationManager loc;
Drawable icon;
String myName;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name = (TextView) findViewById(R.id.name);
thumbnail = (ImageView) findViewById(R.id.thumbnail);
loc = (LocationManager)
getSystemService(Activity.LOCATION_SERVICE);
icon = getResources().getDrawable(R.drawable.icon);
class RoboWay extends RoboActivity {
@InjectView(R.id.name) TextView name;
@InjectView(R.id.thumbnail) ImageView
thumbnail;
@InjectResource(R.drawable.icon) Drawable
icon;
@InjectResource(R.string.app_name) String myName;
@Inject
LocationManager loc;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name.setText( "Hello, " + myName );
}
}
02오픈소스 - Dependency Injection Framework : RoboGuice
• 기본 클래스 Inject 가능
• 로깅기능릴리즈 시 자동으로 디버그 메시지 제거
앱정보 ( 앱이름 , 로그메세지 라인 , TimeStamp, Thread, 다른 유용한 정보 ) 들이
자동으로 로깅 됨
02오픈소스 - Dependency Injection Framework : RoboGuice
RoboGuice 기능
02오픈소스 - Dependency Injection Framework : RoboGuice
• RoboAsyncTask기본적인 AsyncTask 를 확장하고 onException(), onFinally() 통해서 에러처리 가능
• Event handlersOnActivityResultEvent , OnConfigurationChangedEvent,
OnContentChangedEvent, OnContentViewAvailableEvent OnCreateEvent,
OnDestroyEvent 등 많은 이벤트를 받을 수 있도록 어노테이션 지원
※ RoboGuice 2.0 beta3 에서는 더 많은 기능이 추가 됨• Support for Fragments
• RoboApplication 에서 모듈추가를 하지 않고 , res/values/roboguice.xml 외부파일로
모듈을 추가할 수 있음
• Guice 3.0 and Maven 2.0 and 3.0 support
RoboGuice 기능
Custom Class Inject
02오픈소스 - Dependency Injection Framework : RoboGuice
02오픈소스 - Dependency Injection Framework : RoboGuice
Application
RoboApplication
addApplicationModules
AbstractModule
MyModule
configurebind(CustomClass.clas
s)
AbstractModule
MyModule
configurebind(CustomClass.clas
s)
AbstractModule
MyModule
configurebind(CustomClass.clas
s)
…
02오픈소스 - Dependency Injection Framework : RoboGuice
RoboGuice 2.0 beta3 에서는 XML 파일을 이용한Custom Class Injection 가능
02오픈소스 - Dependency Injection Framework : RoboGuice
Reverse Engineeringhttp://goo.gl/h4X4H
02오픈소스 - Dependency Injection Framework : RoboGuice
02오픈소스 - Dependency Injection Framework : RoboGuice
02오픈소스 - Dependency Injection Framework : RoboGuice
02오픈소스 - Dependency Injection Framework : RoboGuice
• 장점1. Dependency Injection Framework 인 Google Guice 를
Android 에서 사용할 수 있다 .
2. 다양한 어노테이션과 기본 클래스들을 사용하여 코드를 줄일 수 있음
• 단점1. 라이브러리 용량문제 (guice-2.0-no_aop + roboguice1.1.2 =
533KB) Making Your App Smaller - http://code.google.com/p/roboguice/wiki/ProGuard
2. 런타임 리플렉션 사용으로 인한 성능저하
RoboGuice 장단점
목차
1. Reflection, Annotation
2. 안드로이드에 Reflection, Annotation
적용해보기
3. 오픈소스
1. Dependency Injection Framework :
RoboGuice
2. Annotation Process Tool Library:
AndroidAnnoations
Contents
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
https://github.com/excilys/androidannotations
androidannotations
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
@EActivity(R.layout.translate)
public class TranslateActivity extends Activity {
@ViewById EditText textInput;
@AnimationRes Animation faceIn;
@Click
void doTranslate() {
translateInBackground(textInput.getText().toString());
}
@Background
void translateInBackground(String textToTranslate) {
String translatedText = callGoogleTranslate(textToTranslate);
showResult(translatedText);
}
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
RoboGuice 와 다르게
AndroidAnnoations
런타임이 아니라 컴파일 시 ,
모든 소스를 자동으로 생성함 .
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
// DO NOT EDIT THIS FILE, IT HAS BEEN GENERATED USING
AndroidAnnotations.
public final class TranslateActivity_ extends
TranslateActivity{
@Override
public void onCreate(Bundle savedInstanceState) {
beforeCreate_(savedInstanceState);
super.onCreate(savedInstanceState);
setContentView(layout.main);
}
private void beforeCreate_(Bundle savedInstanceState) {
}
private void afterSetContentView_() {
textView = ((TextView) findViewById(id.textView));
……
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
APT(Annotation Process Tool)JSR 269(JSR 269 Pluggable Annotation Processing API)
Annotation 을 사용하여 소스 컴파일 전에
사용자가 원한는 작업을 할 수 있도록 하는 규격
Source Code Class fileCompilerAnnotation
Process Tool
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
AndroidAnnotationsClassA.java 를 Annotation Process Tool API 를 통해
ClassA_.java 파일을 생성하여 처리한다 .
1. AndroidManifest.xml 해당 액티비티명 + “_” 추가
2. Intent 를 사용시에 작성한 액티비티명 + “_” 를
추가하여야 함
Cookbook -
https://github.com/excilys/androidannotations/wiki/Cookbook
• Activities : @EActivity
• Application : @App
• View : @ViewById, @AfterViews
• Resource : @StringRes, @ColorRes, @AnimationRes@BooleanRes@ColorStateListRes@DimensionRes@DimensionPixelOffsetRes@DimensionPixelSizeRes@DrawableRes@IntArrayRes@IntegerRes@LayoutRes@MovieRes@TextRes@TextArrayRes@StringArrayRes
AndroidAnnoations 기능
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
• Extras : @Extra
• SystemServices : @SystemService
• Injecting html : @HtmlRes, @FromHtml
• WorkingWithThreads : @Background, @UiThread,
@UiThreadDelayed
• HandlingEvents : @Click, @LongClick, @Touch, @ItemClick,
@LongItemClick, @ItemSelect
• Handling options menu : @OptionsMenu, @OptionsItem
• REST API(With SpringAndroid) : @Rest, @RestService, @Get, @Put,
@Post, @Delete, @Options, @Head, @ Accept
• Trace Method Execution : @Trace
AndroidAnnoations 기능
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
Click Event, Background
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
REST API
AndroidAnnoations +
SpringAndroid
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
Jackson(JSON), Simpleframework(XML) Mashaller
Spring Android(core, RestTemplate)
AndroidAnnotations
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
Spring Android
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(new
MediaType("application","json")));
HttpEntity<?> requestEntity = new
HttpEntity<Object>(requestHeaders);
String url = "http://mypretendservice.com/events";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Event[]> responseEntity =
restTemplate.exchange(url, HttpMethod.GET, requestEntity,
Event[].class);
Event[] events = responseEntity.getBody();
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
AndroidAnnotations REST API@Rest
public interface DaumMovieService {
@Get("http://apis.daum.net/contents/movie?
apikey=DAUM_CONTENTS_DEMO_APIKEY&output=xml
&q={query}")
public MovieContents getMovieContents(String
query);
}
// 실제 액티비티나 서비스에서 사용시 ,
@RestService
DaumMovieService daumMovieService;
• 장점1. Annotation Process Tool 이용하여 컴파일 시에 모든 코드가
생성되어 성능상 이점이 있다 . ( 런타임 시 리플렉션을 사용하지 않
음 )
2. 다양한 커스텀 어노테이션이 제공됨
• 단점1. 인텐트를 사용시 “ _” 문자열 처리
AndroidAnnoations 장단점
02오픈소스 - Annotation Process Tool Library : AndroidAnnoations
02오픈소스 - RoboGuice + AndroidAnnotations
RoboGuice AndroidAnnotations
실제 두 프로젝트는 유사한 점이 있는데AndroidAnnotations 커미터가 RoboGuice
컨트리뷰터로 참여하고 있음
두 프로젝트는 경쟁관계라기보다상호보완적인 관계
02오픈소스 - RoboGuice + AndroidAnnotations
RoboGuice + AndroidAnnotationshttps://github.com/excilys/androidannotations/wiki/RoboGuiceIntegration
Motivation
짜증나는 안드로이드 반복적인 작업
1. UI 매핑 (findViewById)
2. 파라미터 처리 (getIntent().getExtras()….)
3. 비동기처리 (Async)
4. REST 통신 ( Http )
목차
1. Reflection, Annotation
2. 오픈소스
1. Dependency Injection Framework :
RoboGuice
2. Annotation Process Tool Library:
AndroidAnnoations
3. 오픈소스를 넘어…
4. 정리
Contents
03오픈소스를 넘어…
private TextView hello1;
private TextView hello2;
private TextView hello3;
private TextView hello4;
private TextView hello5;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
hello1 = (TextView)findViewById(R.string.hello1);
hello2 = (TextView)findViewById(R.string.hello2);
hello3 = (TextView)findViewById(R.string.hello3);
hello4 = (TextView)findViewById(R.string.hello4);
hello5 = (TextView)findViewById(R.string.hello5);
UI Mapping
직접 내가 한번 만들어보자 .
@ViewById
TextView subject;
@ViewById
TextView write;
@ViewById
TextView date
@ViewById
TextView hit;
03오픈소스를 넘어…
UI Mapping 반복적인 작업 줄이기
; Reflection 사용하기
1. Reflection 으로 액티비티에 선언된 필드 리스트
가져오기
2. 필드명으로 리소스 identifier 값 (R.id.xxxxxx) 을
가져오기
3. findViewById(R.id.xxxxx) 으로 View 가져오기
4. Reflection 으로 필드에 View Injection
03오픈소스를 넘어…
public static void mappingViews(Object object) {
Activity activity = (Activity)object; Field[] fields = activity.getClass().getDeclaredFields(); for (Field field : fields) { String identifierString = field.getName(); int identifier = activity.getResources().getIdentifier(identifierString, "id",
activity.getPackageName()); if( identifier == 0 ) {continue; } View findedView = activity.findViewById(identifier); if( findedView == null ) { continue; } if( findedView.getClass() == field.getType() ) { try { field.setAccessible(true); field.set(object, findedView);
03오픈소스를 넘어…
UI Mapping 반복적인 작업 줄이기
; Reflection + Custom Annotation 사용하기
1. Custom Annotation 만들기 ( InjectView )
2. 필드에서 어노테이션 가져와서 처리
3. BaseActivity 만들어 상속구조로 간소화하기
03오픈소스를 넘어…
1. 어노테이션 만들기
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface InjectView {
int id() default 0;}
03오픈소스를 넘어…
2. 어노테이션 값 가져오기
InjectView injectView = field.getAnnotation(InjectView.class);if( injectView == null )
continue;
int identifier = injectView.id();
03오픈소스를 넘어…
목차
1. Reflection, Annotation
2. 오픈소스
1. Dependency Injection Framework :
RoboGuice
2. Annotation Process Tool Library:
AndroidAnnoations
3. 오픈소스를 넘어…
4. 정리
Contents
Intent
목표
반복적인 코드를 줄일 수 있는
자바의 리플렉션 , 어노테이션을 이해하고
오픈소스 (RoboGuice, AndroidAnnotations) 를
활용하여
작업능률을 높이자 !!!
Q & A질의응답
Twitter : http://twitter.com/geekbeastMail : [email protected] : http://softwaregeeks.org
Thank you!:D