Upload
leonardo-kim
View
1.283
Download
7
Tags:
Embed Size (px)
Citation preview
Modern Android@dalinaum
About me
● GDG Korea Android 운영자○ GDG Korea Android○ http://goo.gl/62bGk
● Google Developers Expert● Thinkware
발표 자료에 대해
이 발표자료는 저, 양찬석님, 전병권님이 작성한 자료를 기준으로 하고 있습니다.
발표자료의 내용은 자유롭게 인용, 발췌할 수 있습니다.
Activity Stack?
● 웹 브라우져에는 왜 저렇게 탭이 많지?● 앱들이 상호작용한다면 모바일 운영체제도 웹 브라우저 처럼 많은 앱이 열리게 될 것임.
● 관리할 방법이 필요함.
Activity Stack
● 연속된 작업 흐름끼리 쌓아 올리자.● 카드덱 1) 메일을 읽던 중 링크를 클릭해서 웹 페이지를 본다.
● 카드덱 2) 사진 촬영 후에 포토원더에서 사진을 편집한다.
● 다른 카드 덱으로 전환: 태스크 전환 버튼● 카드 덱의 카드 제거: 백 버튼
닌겐노 건망증와 튼튼데스네 .
지금 메일을 작성중입니다. 그전에는 무얼 했을까요?
1. 친구 목록을 보다가 이메일 링크를 클릭했습니다.
2. 노티피케이션을 보고 이메일을 클릭해서 답장을 합니다.
3. 메일을 읽다가 답장을 합니다.4. 메일 앱을 클릭해 들어와 메일을 작성합니다.
사용자는 3분만 지나도 뭘 했는지 모릅니다.백 버튼으로 이전 상태로 가는 것이 적절할까요?
업 네비게이션의 도입
● 백 버튼: 이전 상태로 이동.● 업 버튼: 상위 상태로 이동.
액션바
1. 업 버튼a. 캐럿 (<) - 업 네비게이션 가능.b. 로고나 아이콘이 같이 표현
2. 현재 위치나 이동할 수 있는 곳을 표현.a. 탭이나 드로어 메뉴도 사용 가능.
3. 무엇을 할 수 있는지를 표현.a. 액션 버튼. 넘친 항목은 오른 쪽 끝에 점 세개(4)로 표현.
액션바는 허니컴 이후에만 되는 것 아네요?
http://actionbarsherlock.com/프로요까지 지원. 구글도 씁니다.
Jake Wharton (스퀘어)
List 영역 Detail 영역
List영역 Detail영역
Fragment 특징
● 자체의 lifecycle 호출 ( onCreate, onPause 등)○ 동적으로 Fragment의 추가/삭제가 쉽다.○ UI가 아닌 Fragment도 생성 가능
● Activity 가 재생성되도 상태유지가 쉽다.
안드로이드 support library에서 쓸 수 있습니다.
android.support.v4.app.Fragment
타블랫용 layout
깔끔한 Activity 코드
서랍 메뉴 (Drawer Menu)
● 페이스북으로 부터 유행했던 UI 안드로이드에서 공식 지원
● 어떠한 경우에도 액션바가 움직이지 않는 것이 안드로이드 스타일.
● 캐럿 대신에 햄버거 (석삼)이 표시됨
● 메뉴가 열릴 때 상단의 항목은 그대로 배열되고 햄버거의 가로폭만 좁아진다.
● http://goo.gl/LF0nv
더블 버퍼링, 트리플 버퍼링, VSync
● 젤리빈에서 트리플 버퍼링과 VSync 도입?
● 화면에 보여지는 영역: 프레임 버퍼
● 더블 버퍼링: 프레임 버퍼외 백 버퍼를 하나 두는 것.○ 백버퍼 없이 프레임 버퍼에 그리면 그리는 과정 전체가 보이게 됨.
○ 백버퍼에 내용을 그린 다음 프레임 버퍼에 고속 복사하는 방식으로 구현.
○ 문제 주사되는 시점에 복사가 이루어지면 화면의 일부만 복사된 상황에서 표시됨. (티어링 현상)
더블 버퍼링, 트리플 버퍼링, VSync
● 더블 버퍼링 + VSync○ VSync는 주사 주기를 하드웨어로 부터 받아와서 참고하는 것으로 티어링을 피할 수 있다.
○ 이번 주사 주기에 다 못 끝내면 다음 주사 주기까지 기다려야 한다.
○ 렌더링 실패시 성능은 1/N으로 떨어진다.60 프레임 -> 30프레임 -> 20프레임 -> 10프레임.
● 트리플 버퍼링 + VSync○ 백 버퍼를 하나 더 두어서 주사 주기를 기다리는 동안 다른 프레임을 그리자.
○ 밀린 프레임은 해당 프레임에서 밀림.○ 백버퍼의 용량이 추가로 필요.
Show GPU overdraws
UI 상의 불필요한 요소를 쉽게 찾을 수 있습니다. (4.2+)
두개의 옵션을 활성화하십시요.
Worst case
● blue: 1x (2회)● green: 2x● light red: 3x● dark red: 4x
우리의 소원은 2x
1x
2x
3x
4x
왜 배경이 1x일까요?
● window 배경 1회● view 배경 1회● 1 + 1 = 귀요미?
꼭 윈도우 배경 제거합시다.
1x
2x
3x
4x
android:windowBackground @null
getWindow().setBackgroundDrawable(null);
transparent를 하지 맙시다.
1x
2x
3x
4x
overdraw GPU 최적화?
Deferred rendering을 하면 여러번 안 그립니다.
대표적인 구현: SGX
Nvidia 테그라는 무조건 횟수만큼 그립니다.
하드웨어 가속
하드웨어 가속
android:hardwareAccelerated="true"
허니컴 이후 부터 사용 가능.
이후 암시적으로 활성화되지만 명시적인게 좋다고 생각함.
일부 하드웨어가 암시적인 활성화를 무시하기 때문.
디스플레이 리스트
Layer하드웨어 레이어:● 캐쉬를 FBO에 저장.
(FrameBufferObject)● 한정된 영역.● view.setLayerType
(View.LAYER.HARDWARE, null)
소프트웨어 레이어:● 비트맵 보관● view.setLayerType
(View.LAYER.SOFTWARE, null)
다양한 속성에 대한 에니메이션
ValueAnimator: View 이외에도 대부분의 속성에 대해 적용가능한 에니메이터 객체. (HC 11)
linear
non-linear
ValueAnimator va = ValueAnimator.ofInt(0, height); va.setDuration(700); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { Integer value = (Integer) animation.getAnimatedValue(); v.getLayoutParams().height = value.intValue(); v.requestLayout(); } });
에니메이션을 빠르게 하는 방법은 없나요? (JB)
에니메이션을 빠르게 하는 방법은 없나요? (JB)
객체의 프로퍼티에 대한 디스플레이 리스트가 확장.(DLProps)
● alpha● translationX/Y● scaleX/Y● rotationX/YViewPropertyAnimator(HC 12), ObjectAnimator (HC 11)
ObjectAnimator
ObjectAnimator.ofFloat(myObject, "alpha", 0f).start();
객체의 named property에 대한 에니메이션.
ViewPropertyAnimator
myView.animate().alpha(0);
animatingButton.animate().setDuration(2000);
(ObjectAnimator의 쉬운 방법)
SurfaceView's adventures in Wonderland
API에서는 보이지만 회전, 확대, 알파 모든 것이 안됩니다.SurfaceView (+GLSurfaceView)는 View 영역은 아래에 Surface가 보일 수 있도록 투명하게 합니다.(홀 펀칭)
대안: TextureView
뷰의 모든 기능을 사용가능.
GLSurfaceView등의 확장이 없기 때문에 스스로 만들어 써야 함.
3D 그래픽을 하는 것만 조금 까다로움. (기본 코드가 없음.)
젤리빈 이상만 가능.
OpenGL
비동기 처리
● 일정 시간 이상 메인스레드가 동작하지 않으면 ANR 에러.○ 안드로이드는 UI가 메인스레드에서 동작해야 한다.
(아이폰도 UI는 메인스레드에서 존재. 에니메이션만 별도 스레드)
○ DB, 쉐어드프리퍼런스, 파일, 네트워크는 백그라운드 처리되어야 함
비동기 처리
● AsyncTask 모델○ 백그라운드에서 처리해서 메인스레드에 갱신함.○ 작업용 메서드, 후작업용 메서드를 오버라이드하는 형태.
○ 일시적으로 사용할때만 적합하다. (반복적으로 AsyncTask를 호출해야할 수 있음)
○ 엑티비티가 화면 전환 등으로 상태를 잃어버려 계속 호출할 수 있음.
● 스레드 모델○ 메인 스레드와 연결된 핸들러를 이용해야 함.○ 장기적으로 사용할 수는 있음.○ 스레드를 만들어서 관리해야하는 것이 불편.
비동기 처리
● 로더○ 생명주기에 맞추어 작동하는 도구.○ 액티비티 상황에 따라 움직이는 것은 편리.○ 장기적인 작업에는 적당하지 않음.
● 서비스○ 장기적인 작업에 대한 유일한 답.○ 별도의 스레드를 만들어야 하는 것은 불편.
배터리
● 라디오 대기, 라디오 저전력, 라디오 풀 파워의 상태.
● 라디오 대기는 최소 전력이지만 네트워크 지원하지 않음.
● 상태 전환 마다 레이턴시가 있고 효율을 위해 낮은 상태로 가는 것이 더 길게 설정되어 있음.
배터리
● 최악의 경우:○ 네트워크 통신을 1초동안 한다.○ 18초 마다 통신을 한다.○ 1초동안 네트워크 연결을 위해 2초 소모.○ 17초간 절전 모드 들어가지 않음.
● 나누어서 네트워크 잡지 마세요.
Google Play Service
구글 자체 서비스 + 안드로이드를 쉽게 쓰기 위한 서비스 (오픈소스 아님)
● 구글이 만든 HTTPS 확장.● 구글, 페이스 북이 지지.● HTTP 2.0의 근간.
● (HTTP와는 달리) 바이너리 기반 효율적.● 여러 요청을 한번에 처리.● HTTP 의 헤더도 압축. (HTTP는 본문만 압축)● 다른 스트림의 끼어듬 허용. 우선 순위.● 서버 푸쉬 가능 (이 부분만 웹 앱을 새로 적용해야)○ 필요한 이미지나 CSS, JS를 같이 푸쉬시킬 수 있음.
OkHTTP
● HTTPUrlConnection과 동일한 인터페이스● GZIP 압축 지원.● 캐쉬 지원.● SPDY 지원.● 커넥션 풀링 지원.
http://square.github.io/okhttp/ Jesse Wilson (스퀘어, 전직 안드로이드 HTTP 파트 리드)
RetrofitHTTP REST 처리 라이브러리. (http://square.github.io/retrofit/)
public interface GitHubService {
@GET("/users/{user}/repos")
List<Repo> listRepos(@Path("user") String user);
}
GitHubService service = restAdapter.create(GitHubService.
class);
List<Repo> repos = service.listRepos("octocat");
HTTP / 이미지 라이브러리 샘플들http - OkHTTP 간단한 샘플로 main함수가 있는 코드들이 있습니다.https://github.com/swankjesse/android-http-examples/tree/master/http
picasso-app - 스퀘어의 이미지 라이브러리 피카소에 대한 샘플들입니다.https://github.com/swankjesse/android-http-examples/tree/master/picasso-app
retrofit-app - 역시 스퀘어가 만든 어노테이션 기반의 HTTP(JSON) 도구 레트로핏에 대한 샘플들입니다.https://github.com/swankjesse/android-http-examples/tree/master/retrofit-app
volley-app - 구글이 만든 발리 라이브러리에 대한 샘플입니다.
https://github.com/swankjesse/android-http-examples/tree/master/volley-app
Android Annotation
http://androidannotations.org/
AndroidAnnotations is an Open Source framework that speeds up Android development.
It takes care of the plumbing, and lets you concentrate on what's really important. By simplifying your code, it facilitates its maintenance.
관용어!
findViewById...
(...)getSystemService...
setOnClickListener...
runOnUiThread(new Runnable()...
new Thread().start...이정도는 괜찮지만 재미없어
요.
@EActivity(R.layout.translate) // Sets content view to R.layout.translatepublic class TranslateActivity extends Activity {
@ViewById // Injects R.id.textInput EditText textInput;
@ViewById(R.id.myTextView) // Injects R.id.myTextView TextView result;
@AnimationRes // Injects android.R.anim.fade_in Animation fadeIn;
@Click // When R.id.doTranslate button is clicked void doTranslate() { translateInBackground(textInput.getText().toString()); }
@Background // Executed in a background thread void translateInBackground(String textToTranslate) { String translatedText = callGoogleTranslate(textToTranslate); showResult(translatedText); } @UiThread // Executed in the ui thread void showResult(String translatedText) { result.setText(translatedText); result.startAnimation(fadeIn); }
// [...]}
Otto
http://square.github.com/otto/Otto is an event bus designed to decouple different parts of your application while still allowing them to communicate efficiently.Forked from Guava, Otto adds unique functionality to an already refined event bus as well as specializing it to the Android platform.
Guava
The Guava project contains several of Google's core libraries that we rely on in our Java-based projects: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth.
https://squareup.com/https://github.com/square
Event Bus= transfer 'Event' between components= listeners?
http://en.wikipedia.org/wiki/Bus_(computing)
Listener vs Event Bus
여러 프래그먼트를 사용하는 앱
A B C 1. 인터페이스를 만듭니다.
2. 인터페이스를 구현합니다 .
3. 프래그먼트로 메시지를 전달합니다 .
다른 프래그먼트와 소통하기
http://developer.android.com/training/basics/fragments/communicating.html
public static class MainActivity extends Activity implements FragmentA.OnFragmentListener, FragmentB.OnFragmentListener, FragmentC.OnFragmentListener {
....
@Override public void onFragmentA () {
}
public void onFragmentB() {}
}
public class FragmentA extends Fragment { OnFragmentListener mCallback;
// Container Activity must implement this interface public interface OnFragmentListener { public void onArticleSelected (int position); }
@Override public void onAttach(Activity activity) { super.onAttach(activity); try { mCallback = (OnFragmentListener ) activity; } catch (ClassCastException e) { throw new ClassCastException (activity.toString() + " must implement OnFragmentListener" ); } } ...}
1. 인터페이스 정의하기
2. 인터페이스 구현하기
public static class MainActivity extends Activity implements FragmentA.OnFragmentListener, FragmentB.OnFragmentListener, FragmentC.OnFragmentListener { ...
public void onArticleSelected (int position) { // The user selected the headline of an article from the FragmentA // Do something here to display that article
FragmentA articleFrag = (FragmentA) getSupportFragmentManager ().findFragmentById (R.id.article_fragment );
if (articleFrag != null) { // If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content articleFrag .updateArticleView (position); } else { // Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article FragmentA newFragment = new FragmentA (); Bundle args = new Bundle(); args .putInt(FragmentA .ARG_POSITION , position); newFragment .setArguments (args); FragmentTransaction transaction = getSupportFragmentManager ().beginTransaction ();
// Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack so the user can navigate back transaction .replace(R.id.fragment_container , newFragment ); transaction .addToBackStack (null);
// Commit the transaction transaction .commit(); } }}
3. 프래그먼트로 메시지 전달하기
3단계 Otto
1. 이벤트 버스를 만듭니다.
2. 이벤트를 발행합니다.
3. 이벤트를 구독합니다.
@Subscribe
public void answerAvailable(AnswerAvailableEvent event) { // TODO: React to the event somehow!}
bus.register(this);
bus.post(new AnswerAvailableEvent (42));
Bus bus1 = new Bus();Bus bus2 = new Bus(ThreadEnforcer.MAIN);
기타 유용한 라이브러리
Pull-to-refresh
https://github.com/chrisbanes/Android-PullToRefresh
구글에 입사!
ImageLoader
캐싱지원, 사용이 쉽다.
http://androidimageloader.com/
HttpResponseCache
Http응답을 캐싱해주는 라이브러리Android 4.0 이상의 android.net.http.HttpResponseCache 의 Backport
https://github.com/candrews/HttpResponseCache
google-gson
json을 Java Object로 변환해주는 라이브러리
https://code.google.com/p/google-gson/
String json = "{1, 2, 3, 4, 5}";
int[] array = gson.fromJson("[1,2,3,4,5]", int[].class)
jsoup
Beautiful Soup(Python Html 파싱 라이브러리)의 자바 버전
http://jsoup.org/
acra(Application Crash Report for Android)앱 크래시 정보를 특정서버로(Google Doc, 자체서버 등)으로 전송해주는 라이브러리
http://acra.ch/
기타 참고
● Fragment 시작하기 - http://goo.gl/6k5Jj● TextureView Demo - http://goo.gl/5NyI2● 배터리를 절약하는 네트워크 어플리케이션의 구현http://huewu.blog.me/110150046116
● 비동기를 위한 Loader - http://goo.gl/lU0qk● SPDY는 무엇인가? - http://goo.gl/57MK2●