25. Part I. UI Layer
UI
Network
Common
BaaS
UI BindingUI Pattern HybridActionbar
(Un)Marshller + Dispatcher(Un)Marshaller SNS
DILogging Lightweight DI
LoggingUser Behavior
Open Source Bas
s
Notification
35. Instability
•패키지의 움직일 수 있는 여력을 판단하는
지표
•다른 패키지에 영향을 미치지 않고,
해당 패키지를 쉽게 변경 할 수 있는가?
•Instability I = Ce / (Ca+Ce)
•Ce = Efferent Coupling (Ingoing Dependencies)
•Ca = Afferent Coupling (Outgoing Dependencies )
36. Instability
Instability I = Ce / (Ca+Ce)
당신의 패키지가 다른 사람이 많이 쓴다면,
즉 Outgoing, Ca가 많다면, 여러분의 패키지는 변경하기 어렵다.
반대로 Outgoing하는 Ca가 적고, Ingoing(다른 패키지만 사용만 하는) Ce,
여러분의 패키지는 쉽게 변경해도 된다.
즉 0.0에서 0.3이면 안정적인 버전, 0.7에서 1.0이면 불안정적인 상태다
37. Abstractness
Interface(Abstract) 와 Concrete Class를 비교
A = (#abstract classes / total # of classes)
•Abstract class = interface, abstract다 포함
•Total # class = abstract class + concrete class
•0 이면 concrete class만 있다.
•1 이면 abstract class만 있다.
71. COCOS2D 게임 엔진을 이용하여 자동 스케일링 후 나머지 부분 Crop
갤럭시 노트
16:10 (1280*800)
2. 기기 해상도에 따른 문제!!
갤럭시 S3
16:9 (1280*720)
옵티머스 뷰
4:3 (1024*768)
72. Cocos2D 사용 시...
- Cocos2D로 UI를 나타낼 View 설정
- Handler 객체 전달하여 Activity와 통신
- Activity Context 전달
- String Resurce 가져오기
- 진동, 전화 등과 같이 안드로이드 시스템 서비스
사용시
73. 3. 언어별 글자 길이 문제
한국어 : 배고픈 양에게 먹이를 주세요!
중국어 : 主人,放飯的時間到了!
일본어 : たいへん、ひつじが腹ペコ!
餌を与えて
영어 : Feed the hungry sheep !
74. Custom TextView
• 글자 길이가 지정된 길이를 초과한다면 지정된 길이를 초과하지 않도
록 폰트 사이즈 조절
• 문자열에 개행(n) 문자가 있다면 문자열들을 개행 문자 기준으로 나
눈뒤 가장 긴 부분 기준으로 폰트 사이즈 조절
• 설정된 텍스트 뷰 길이 기준으로 원하는 비율이 문자열의 최대 길이
가 될수 있도록 폰트 사이즈 조절
78. 원하는 가로 비율만큼만
문자열 배치
개행문자 기준으로
가장 긴 문자열 찾기
이진 탐색을 통해서
최적의 Font Size 계산
79. Part 2. Network
UI
Network
Common
BaaS
UI BindingUI Pattern HybridActionbar
(Un)Marshller + Dispatcher(Un)Marshaller SNS
DILogging Lightweight DI
LoggingUser Behavior
Open Source Bas
s
Notification
108. RestAdapter restAdapter = new
RestAdapter.Builder()
.setServer(new Server(“https://api.github.com/”))
.setClient(new DefaultHttpClient())
.setConverter(new GsonConverter(new Gson()))
.build();
GitHub github =
restAdapter.create(GitHub.class);
User me =
github.getUser("realbeast");
실제 통신
112. General Collaboration
INITIALIZE
REGISTER HANDLER
EXTRACT HANDLE
RUN EVENT LOOP
WAIT FOR EVENTS
DISPATCH
HANDLER(S)
handle_event(event_type)
get_handle()
register_handler()
Initiation Reactor
select()
Main
program
Concrete
Event_Handler Reactor
handle_events()
EVENTHANDLING
MODE
INITIALIZATION
MODE
Synchronous
Event
Demultiplexer
event
handles
1 … N
113. Implement
Demultiplexing Table
• This table contains a set of
– <handle, event handler, indication event types>
• Demultiplexing table can be implemented
– Direct indexing, linear search, dynamic hashing
Reactor
handle_events()
register_handler(in handle)
remove_handler(in handle)
Handle
handle
set
Each handle serve as a “key”
Reactor
Handle Table
Concrete
Event Handler
Concrete
Event Handler
114. 10/1/2013 Devpia A&D EVA 114
Dispatcher + Marshaller
Dispatcher
+select()
+handle_events()
+register_handler()
+remove_handler()
Acceptor
+peer_acceptor_
+Acceptor()
+accept()
+handle_event()
Transport
Handle
Connector
+Connector()
+connect()
+complete()
+handle_event()
Service Handler
+peer_stream_
+open()
+handle_event()
+set_handle()
Concrete
Connector
Concrete
AcceptorConcrete
Service
Handler
B
Concrete
Service
Handler
A
Transport
Handle
Transport
Handle
+owns
+owns
+uses
* +uses
*
+uses
*
+uses
owns
notifies
notifies
<<creates>>
<<activate>><<activate>>
121. About Graph API
• Graph API
– 소셜 그래프의 Object(친구, 페이지, 사진 등)를 다루는 API
• Graph API의 구조
– https://graph.facebook.com/OBJECT_ID/CONNECTION_TYPE
• ID는 사용자, 페이지, 이벤트, 사진 등의 Object ID
– 약 20개의 Object를 지원
– 모든 Object의 ID는 unique하다
– JSON 형태로 응답을 받는다
121
122. Graph API Example
• https://graph.facebook.com/100001066448386/
• https://graph.facebook.com/40796308305/
122
신재명 ID
코카콜라 페이지 ID
123. Graph API - Connection
• Graph API의 구조
– https://graph.facebook.com/OBJECT_ID/CONNECTION_TYPE
• Connection이란 ?
– Object의 연관(관계) 개념
• User object의 Connection 종류
– Family, friends, album, likes, posts …
– User object 경우 약 25개의 Connection 을 제공
– https://developers.facebook.com/docs/reference/api/user/ 참고
123
124. Connection - Example
• Graph API 예시
– https://graph.facebook.com/100001066448386/friends
그럼 보안문제는 ???
124
125. Access Token
• 페이스북 API를 사용하기 위해 Access Token(인
증)이 필요하다.
• Graph API Explorer를 통하여 쉽게 Access Token
을 받아올 수 있음
125
126. About Graph API
• Graph API Explorer
– Access Token 받을 수 있다
– 각종 Graph API를 테스트 해볼 수 있다
https://developers.facebook.com/tools/explorer#!/tools/explorer
155. Part 3. Common
UI
Network
Common
BaaS
UI BindingUI Pattern HybridActionbar
(Un)Marshller + Dispatcher(Un)Marshaller SNS
DILogging Sensing
LoggingUser Behavior
Open Source Bas
s
Notification
171. RoboGuice 기능
• RoboAsyncTask
기본적인 AsyncTask를 확장하고 onException(),
onFinally() 통해서 에러처리 가능
• Event handlers
OnActivityResultEvent , OnConfigurationChangedEvent, OnCo
ntentChangedEvent, OnContentViewAvailableEvent
OnCreateEvent, OnDestroyEvent 등 많은 이벤트를 받을 수 있도록
어노테이션 지원
172. 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. 런타임 리플렉션 사용으로 인한 성능저하
181. // DO NOT EDIT THIS FILE, IT HAS BEEN GENERATED USING AndroidAnnotatio
ns.
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));
……
185. • 장점
1. Annotation Process Tool 이용하여 컴파일 시에 모든 코
드가 생성되어 성능상 이점이 있다. (런타임 시 리플렉션
을 사용하지 않음)
2. 다양한 커스텀 어노테이션이 제공됨
• 단점
1. 인텐트를 사용시 “_” 문자열 처리
AndroidAnnoations 장단점
198. Who is Funf for?
• Self – Tracking
– Funf Journal 이라는 앱을 통해 원하는 센서 값만 받아
볼 수 있다. 개인적으로 자신의 데이터를 분석하는데
사용
• Study Managers/Researchers
– 센서를 통해얻는 여러 정보들을 모아서 분석하고 연구
• API-Level Developers
– Funf의 내부단을 사용하지 않고 3rd-party 개발자 API만
사용하여 개발 할 수 있도록 해준다
• Core-Level Developers
– Funf에 없는 새로운 센서를 추가하거나 기존에 있는 센
서 측정의 performance를 높인다
201. Funf journal
• 수집된 데이터는 *.db 파일이며, 암호화 되어있다
– 디코딩 프로그램제공(http://funf.media.mit.edu/downloads/funf_analyze_win.zip)
– JSON 형태의 결과 데이터
202. Funf in a box
• Researcher 용으로 여러 테스터들에게서 원하는 센서데
이터들을 수집하는데 사용
• 간단하게 데이터 수집용 앱을생성
• APP 이름, 데이터를 받을 e-mail,
수집할 센서정보를 세팅 한 후
생성하면 .apk 파일을 얻을 수 있다.
203. Funf in a box
• .apk 파일은 Dropbox를 통해서 받을 수 있다
– https://www.dropbox.com/
204. Key feature
• 수집된 데이터는 JSON 형태
• 수집데이터를 원격지에 주기적으로 보낼 수 있다
• 약 30여개의 probe 제공
• 암호화를 통해 민감한 정보를 숨김(폰번호, 이름 등)
• 로컬 저장하는 DB 파일은 암호화되어 저장됨
• 15개월의 테스트를 통해 프레임웍을 검증
• 배터리 소모량 최적화
205. Tutorial
• Google code에 source 및 각종설명
– http://code.google.com/p/funf-open-sensing-framework/wiki/GettingStarted?tm=6(wiki)
• Git 을 통해 소스 배포
– https://code.google.com/p/funf-open-sensing-framework.samples(샘플)
– https://code.google.com/p/funf-open-sensing-framework (funf framework)
• Jar file로도 제공
– http://code.google.com/p/funf-open-sensing-framework/downloads/list
206. Tutorial
• Probe 정보
– http://code.google.com/p/funf-open-sensing-framework/wiki/BuiltinProbes
• Probe parameter
– Period
– Duration
– Start
– End
211. Tutorial(Example)
• Merged_data.db 생성됨
– Id : unique id for the data entry
– Device : UUID for the device
– Timestamp : long, UTC in seconds since epoch
– Value : result data in json format
220. ParseObject gameScore = new
ParseObject("GameScore");
gameScore.put("score", 1337);
gameScore.put("playerName", "Sean Plott");
gameScore.put("cheatMode", false);
gameScore.saveInBackground();
데이터 저장하기
Key-value 된 값을 저장
238. • http://bit.ly/KnZzpx 에서 소스코드 다운
• Android 프로젝트
src/폴더에 소스코드 추가
• AndroidManifest.xml에 퍼미션 추가
<uses-permission
android:name="android.permission.INTERNET“>
239. • 클래스 내부에 session object 추가
• Main Activity에 Import
• OnCreate 함수에 아래 소스 추가
import com.localytics.android.*;
private LocalyticsSession localyticsSession;
public void onCreate(Bundle savedInstanceState)
{ .
.
.
this.localyticsSession = new LocalyticsSession(this.getApplicationContext(),
"APP KEY FROM STEP 2");
this.localyticsSession.open(); // open the session
this.localyticsSession.upload(); // upload any data
.
.
.
}
245. MicroLog4Andorid
public class LogtestActivity extends Activity {
static public Logger logger = LoggerFactory.getLogger();
@Override
public void onCreate(Bundle savedInstanceState) {
PatternFormatter formatter = new PatternFormatter();
formatter.setPattern( " %d{ISO8601} [%P] %m %T " );
logger.setLevel(Level.INFO);
// write to LogCat
LogCatAppender logCatAppender = new LogCatAppender();
logCatAppender.setFormatter(formatter);
logger.addAppender(logCatAppender);
// write to text file of SD-card.
FileAppender fileAppender = new FileAppender();
fileAppender.setAppend( true );
fileAppender.setFileName( "microlog4android.log" );
fileAppender.setFormatter(formatter);
logger.addAppender(fileAppender);
소스 내부에서
설정
로그를 보내는
기능이 없다
252. 로깅 방법
public class LogtestActivity extends Activity {
static public Logger logger = LoggerFactory.getLogger();
@Override
public void onCreate(Bundle savedInstanceState) {
PatternFormatter formatter = new PatternFormatter();
formatter.setPattern( " %d{ISO8601} [%P] %m %T " );
logger.setLevel(Level.INFO);
// write to LogCat
LogCatAppender logCatAppender = new LogCatAppender();
logCatAppender.setFormatter(formatter);
logger.addAppender(logCatAppender);
// write to text file of SD-card.
FileAppender fileAppender = new FileAppender();
fileAppender.setAppend( true );
fileAppender.setFileName( "microlog4android.log" );
fileAppender.setFormatter(formatter);
logger.addAppender(fileAppender);
253. 로깅 방법
public class LogDogClient extends Application {
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
LogDog.LogDoginitialize(this,"설정.xml");
}
}
258. 버그 리포팅
ReportTime 에러 발생 시간
Model 스마트폰 모델명
National 발생 국가
ErrorName 에러 이름
ErrorClassName 에러 클래스 이름
Line 에러 라인
AppVersion 앱버전
OSVersion OS버전
GPS GPS상태
WiFi WiFi 상태
MobileNetwork 3G상태
ScreenWidth 스크린 크기
ScreenHeight 스크린 크기
CallStack 콜스택 정보
Log 로그 정보
272. LogDog - 에러 분포 리포트 제공
에러가 발생하는
클래스의 분포도를 한눈에 파악할 수 있는 리포트
273. LogDog web의 초기 구조
Error
Google App
Engine
Data
Store(HighChart, jqGrid,
Bootstrap)
Web
JDO
JDO
에러
Java- servlet
274. Servlet만을 이용한 개발
1. 개발하기가 다른 것에 비해 힘들다.
2. 유지보수가 힘들다.
3. 특히 다른 개발자가 구조를 파악하기 힘들다.
이게 도대체
무슨 구조야?
275. Jersey 1.15
http 메소드:
get, post, put ,delete
REST 기반 서버 구성
REST: ROA(Resource Oriented Architecture)를
따르는 웹 서비스 디자인 표준
REST 서버 구축을
도와주는 오픈소스
URL
276. GAE – frontend
GAE Frontend의 한계
작업 요청
30초 내에 응답
(못하면 자동 취소)
Data Store의 정보를 Select 하는 경우는 빠르지만,
Insert, Update는 오랜 시간이 걸려 문제 발생!!
277. GAE – Backend
GAE Backend
작업 요청
Task queue
작업 등록
Backend는 30초의 시간 제한이 존재하지 않는다.
Task Queue
작업이 승인됨을 알림
Data
Store
GAE
Backend
Queue에 등록된
작업을 가져옴 작업 등록
278. Logdog web의 작동 구조
Error
GAE
Backend
Google App Engine
Jersey
1.15
Data
Store
Task Queue
(HighChart, jqGrid,
Bootstrap)
Web
JDO
JDO
에러
앞에 일반적인 방법에는 그대로 출시하기엔 비효율적인 요소부터 많은 문제점들이 있습니다.어떤 문제점이 있는지 살펴보도록 하겠습니다.
앞의 예제에서는 모든 네트워크 요청이 순차적으로 일어납니다.따라서 스크롤을 내려서 다음페이지를 읽어려고 해도 전 페이지의 로딩이 끝나야지만 넘어 갈 수 있습니다.Volley 에서는 쓰레드풀 관리를 통해 네트워크 요청을 자동으로 스케쥴링 하고 있습니다.Playstore에 적용하여 테스트한 결과 4개의 쓰레드일때가 가장 퍼포먼스가 좋아서 디폴트는 4개이나 사용자가 임의로 수정도 가능합니다.또한 volley에서는 요청 우선순위도 설정할 수 있기 때문에 이미지로딩에 낮은 우선순위를 주어서 제목이나 내용 부터 로딩하는 등의 방법이 가능합니다.
화면 회전시 Activity가 재 생성되고 처음부터 모든 네트워크 작업이 다시 일어납니다. 이를 해결하기 위해 많은 분들이 cache를 이용해 저장하고 다시 불러오는 작업들을 하고 계시는데Volley를 이용하면 이런 불편한 작업들을 해결할 수 있습니다.Volley에서는 사용자가 캐쉬를 신경쓰지 않더라도 자동으로 캐쉬되어 네트워크에서 reload 하지않고 불러옵니다.
이미지요청을날리고 그 사이에 사용자가 스크롤을 내렸다면 view를 재활용할 수가 없습니다.이런 불편함을 해소하기 위해 Volley는 요청 취소 기능을 제공하기 때문에 원하는 요청을 취소 할 수 있습니다.
진저브레드 이전까지의 HttpURLConnection은 문제가 많았었는데,volley를 이용하면 쉽게 네트워크 레이어를 변경함으로써 자신의 버전에 맞는 네트워크 레이어를 사용할 수 있습니다.
JsonObjectRequest를 이용하여 데이터를 받아와서 파싱 후 display하는것까지 boilerplate 코드 없이 잘 이루어져 있습니다