'[+++ JAVA +++]'에 해당되는 글 50건

  1. 2015.01.18 모바일 DB Realm (렘) 개날림정리
  2. 2015.01.17 android lollipop에서 구동시 마주친 문제
  3. 2014.12.24 Robolectric 적용시 NoClassDefFoundError: com/google/android/collect/Maps 날때..
  4. 2014.12.22 AndroidStudio 커서를 이클립스처럼 camelcase 단위로 옮기기 (1)
  5. 2014.12.14 Android wear Watch face Code Sample
  6. 2014.12.14 Android wear Watch face 디자인하기
  7. 2014.12.09 AndroidStudio 1.0 rc4 에서 1.0 릴리즈로 업데이트시 apt 처리 문제 해결방법
  8. 2014.12.08 Mockito 를 이용한 Callback test
2015.01.18 00:20

Deview2014 에서 직접 세션을 듣진 않았지만 대충 이런 모바일 DB가 뜬다는것만 알고 있었는데, 이번에 기회가 되서 함 정리해봄.


sqlite 는 너무 옛날에 사용해서 비교하지 못할거 같음.


Realm realm = Realm.getInstance(contex);


로 인스턴스를 가져오고 원하는 작업을 할 수있는데 먼저 Realm의 특징은 매우 빠르고, jpa 처럼 객체자체를 집어넣을 수 있는 ORM 이다. 그런데 뭔가 불편한 점이 있는데, 모델이 되는 객체는 반드시 RealmObject를 상속해야하고, 매서드로 getter/setter 만 가질 수 있다는 점이다.(0.76.0 기준, 다른 매서드가 들어가니 빌드 에러가 난다 -> 어노테이션프로세싱을 하기때문에 매서드 중복을 막기위해서 막아둔것 같다. 아니 그러면 차라리 모두 어노테이션프로세싱으로 돌려야지!? 불편하게 이게 뭐야....-> 음. 아직 모르는 기능인가보다.) 이게 왜 짜증나나면, DDD방식으로 개발하려면 모델자체가 어떤 간단한 기능들을 내포할 수 있어야 하는데 이게 불가능해지니...그래서 차라리 디비엔 Dto(Vo)를 널고 읽어온뒤에 오브젝트매퍼같은 녀석을 이용해 매핑해주면 그나마 편리하게 이용할 수 있을것 같다. 


쨋든, 처음에 객체를 만들땐 반드시 realm 인스턴스를 통해서 만들어야 저장이 된다. 따로 save 매서드가 있는지는 모르겠다.


realm.beginTransaction();

MyDto dto = realm.createObject(MyDto.class);

realm.commitTransaction();


쿼리할땐 where clause를 이용해서 할 수 있다. 그런데 스트링매치에 대해선 beginWith, endWith, contains 밖에 없는듯한데, like clause 가 없어서 좀 불편하다. 와일드카드가 먹히는지는 아직 확인해보지 않았다. (메서드 이름만 봐도 안되는거 같기도...)


MyDto first = realm.where(MyDto.class).findFirst();


dsl 로 여러가지 작성할수 있어서 좋긴함.


삭제의 경우 처음에 deleteRealmFile 를 사용했었는데 이게 파일을 삭제하는거다보니 문제가 조금 있었다. 

드랍 테이블과 같은 효과를 내기 위해선 그냥 clear 또는 realm.allObjects(MyDto.class).clear();와 같이 해주면 된다.


한글로 정리된것도 있어서 좋다.

http://realm.io/kr/

http://realm.io/kr/docs/java/0.75.0/


사실 저기 홈에 나온 코드만 봐도 끝인거 같다.


나머지는 예제를 보면 좋을거 같은데 예제를 androidstudio에서 열었더니 굉장히 오랫동안 로드를함..(macbook air 2013) 그마저도 약간 빌드가 꼬인거 같아서 걍 버리고코드만 구경했음.


뉴스에 있던 코드인데 이것만 봐도 90%는 알 수 있는거 같다.


Realm realm = Realm.getInstance(this);

// All writes are wrapped in a transaction
// to facilitate safe multi threading
realm.beginTransaction();

// Add a person
Person person = realm.createObject(Person.class);
person.setName("Young Person");
person.setAge(14);

realm.commitTransaction();

RealmResults<User> result = realm.where(User.class)
                                 .greaterThan("age", 10)  // implicit AND
                                 .beginGroup()
                                      .equalTo("name", "Peter")
                                      .or()
                                      .contains("name", "Jo")
                                 .endGroup()
                                 .findAll();



저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2015.01.17 14:17

1. AndroidAnnotations의 @Background에서 TextView의 setEnabled()을 호출했을때 에니메이션은 Looper thread 에서만 돌아야 한다는 에러

-> 롤리팝으로 올라가면서 Drawable 의 state가 변경될때 마다 에니메이션을 하는데 이게 백그라운드 쓰레드에서 안된다는것. 이전 버전들에서는 이런 에니메이션이 없기 때문에 상관이 없지만.. 특히 xml에서 setEnabled = false 처럼 값을 주게 되면 코드상에서나 xml에서나 뭐가 문제인지 알기 힘들어짐. 

해결방법: 에니메이션처리를 위해 해당 위젯을 메인쓰레드에서 setEnable을 해준다. 또는, 반드시 백그라운드쓰레드에서 돌았으면 하는것들은 android:stateListAnimator="@null" 로 세팅한다. 코드에선 view.setStateListAnimator(null); 인것 같은데 티스트 해보진 않음.


2. ActionMenu 관련 문제가 날때

values-v21디렉터리만들고 그 안에 스타일이나 테마를 넣어준다. 내 경우는 엑션바의 more버튼 눌렀을때 메뉴가 흰색인데 글씨도 흰색이라서 기본 values의 theme.xml에서 이 색을 지정해줬었는데 이때 롤리팝에선 이 색상을 걍 단순히 하나만 줘서 되는것이 아니라 리스트로 줘야함. 그래서 캐스트익셉션이 났던거 같음. 하지만 사실 내 문제의 근본적인 문제가 액션바의 메뉴였으므로 그냥 기본 패런트의 테마를 수정함으로써 해결함. 

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2014.12.24 14:32

예전 맥북에어에서 사용할땐 잘 되던것이 이번에 맥프레로 개발환경을 옮기면서 테스트가 다 깨졌었는데, 그때 에러가 바로

NoClassDefFoundError: com/google/android/collect/Maps#1420


https://github.com/robolectric/robolectric/issues/1420



문제는 버전이었는데 그래들엔 2.4를 쓰고 있었는데 2.4에는 com.google.android 디팬던시가 없어서 클래스를 못찾던것. 그래서 버전을 2.3으로 낮추니 잘 돌아감.


현재 com.google.android 디팬던시를 모두 없애도 있다고 하니 차기 버전에서는 해결될듯


버전을 2.3으로 낮추고 잘 동작하길래 이슈를 닫았더니, 다시 제이크 왓슨님이 손수 오픈하심ㄷㄷ


이런 영광이..ㅋㅋ

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2014.12.22 11:04

커서를 옮길때 alt+화살표 로 자주 옮기는데, AndroidStudio(intellij 도 마찬가지일듯) 기본값으로 단어 기준을 문법상 단어로 잡혀있어서 매서드 이름, 변수 이름등은 하나의 단어로 생각함.

이클립스의 경우 매서드 이름, 변수 이름등을 또 내부적으로 실제 단어 기준으로(사실은 특문(_)이나 숫자, 카멜케이스단위로)해서 alt+를 이용한 커서 를 옮길때 편리함.



저 옵션을 활성화 하면 이클립스랑 비슷하게 카멜단위로 점프를 할 수 있음

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 1
  1. Favicon of http://quadflask.tistory.com BlogIcon Flask 2014.12.22 11:20 신고 address edit & del reply

    부작용으로 더블 클릭으로 단어 선택시에도 단어 단위로 선택이 됨....뭐 이런.....

2014.12.14 12:54

Android Wear API 가 새로 공개된 기념으로 코드 샘플을 보고 있는중에 중요한 부분들 기록


1. 퍼미션, 인텐트 필터 등록

일단 패키지 네임은 동일하다.


폰 어플리케이션 AndroidManifest.xml


웨어 AndroidManifest.xml


2. CanvasWatchFaceService 상속 및 Engine 인스턴스 리턴

여기는 폰용 WallpaperService랑 거의 같음.


3. onCreate 매서드를 오버라이딩하고 필요한 초기화 작업 수행

setWatchFaceStyle 에서 몇가지 값들을 셋하는데 Doc 을 참고해야할듯


4. onDraw매서드 오버라이딩하고 시계를 랜더링 한다

이 예제에선 Time 객체를 사용하는데 이게 편할듯(setToNow로 시, 분, 초 다 가져오기 편하다!)


5. onAmbientModeChanged 매소드 오버라이딩하고 앰비언트 모드 전환시 이벤트를 받는다

이 예제에선 단순히 안티 앨리어싱 옵션만 on/off 하고 있다. 여기서 중요한것이 invalidate()를 해준다는점. 그리고 updateTimer()를 호출하고 있는데 이 메소드는 단순히 핸들러에 메시지를 날리는것인데,,,핸들러 내부에서 자기 자신에게 다시 매시지를 날려서 진행하고 있음.(왜 이렇게 하는거지? 그냥 타이머 객체 사용해서 타이머태스크를 구현하면안되나?)

->

여기 핸들러를 보면, 타이머가 동작해야할때에 대해서 메시지를 호출하는데 이때 딜레이를 계산하는 부분이 중요하다. 하지만 이 부분은 굳이 이렇게 까지 복잡하게 할 필요 없이 Timer 클래스와 TimerTask 를 이용하면 자연스레 쉽게 구현이 가능해진다. 하지만 여기서 핸들러를 사용하는 이유는 아마 뷰의 invalidate() 때문인것 같다.


6. onInterruptionFilterChanged 메소드 오버라이딩하고 시계의 뮤트여부에 따라 콘트라스트를 조절한다.

시계에 뮤트 옵션이 있는거 같은데...이 뮤트상태일땐 화면의 콘트라스트를 낮춰야 한다.(밝기를 낮춰야 한다. 그래서 여기선 알파값을 조절해서 100% -> 약 39%로 낮추고 있다)



잘못된 부분은 언제나 피드백 환영합니다.

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2014.12.14 01:07

Designing Watch Faces:

Watch Faces for Android Wear


원글 : http://developer.android.com/training/wearables/watch-faces/designing.html


간단한 가이드 라인 부분만 발번역해봄


Plan for Square and Round Devices

네모랑 동그란 디바이스를 염두해야 한다는 내용

(갤럭시 기어가 네모, G 와치가 동그라미인데....동그라미가 더 이뻐보임..)


Create flexible concepts

이상적으로 와치페이스의 시각적 기능은 동그라미나 네모 둘다에 대해서 동작해야 합니다. 이 예에서는 와치 페이스는 시각적 기능이 다른 조절 필요 없이 충분히 유연하게 동작합니다. 그러나 다른 디자인 컨셉들은 네모나 동그라미 스크린에 대해서 다른 실행을 필요로 합니다.

-> 네모나 동그라미에 대해서 비슷한 느낌을 줄 수 있도록 해야 한다.


Use a common design language

동그라미나 네모에 대해서 서로 시각적으로 연결하기 위해 흔한 색상, 라인 두께, 쉐이딩, 그외 디자인 요소를 사용하세요. 비슷한 색상 팔레트를 사용하고 약간의 시각적 연관성을 사용함으로써 네모, 동그라미의 전체적인 모습이 조금 커스터마이징 될 수 있지만 여전히 같은 시각 시스템으로 느낄 수 있다.

-> 네모나 동그라미에 대해서 인식한뒤, 그에 맞는 모습을 보여주되 너무 다르게 느끼지 않도록 커스터마이징 해야한다. (그냥 동그라미만 지원한다...를 정할 순 없나..?)


Adjust for analog concepts

몇가지 컨셉들은 자연적으로 시침, 분침이 있는 아날로그 시계의 모습을 가질것입니다. 이 경우 네모로 변환할때  모서리부분을 고려하세요. 다른 여백(?) 공간을 활용하세요.



Plan for All Display Modes

모든 디스플레이 모드에 대해서 계획하세요


안드로이드 웨어 디바이스는 크게 두가지 모드로 동작합니다: 앰비언트(주변광?), 인터렉티브(상호작용?)입니다. 와치 페이스 디자인은 이 두가지 모드에 대해 디자인 되어야 합니다. 보통 와치 페이스 디자인이 앰비언트모드에서 좋게 보인다면, 인터렉티브 모드에선 더 멋지게 보일것입니다.


앰비언트 모드에선 스크린은 매 분마다 업데이트 됩니다. 오직 시, 분만 보여집니다. 이 모드에선 초를 표시하지 마세요.


Interactive mode

유저가 와치를 건들였을때(?) 스크린은 인터렉티브 모드로 전환됩니다. 이 모드에선 모든 색상, 그리고 자연스러운 에니메이션을 사용 할 수 있습니다.


Ambiend mode

(어디서 주워 듣기론 모든 배경은 반드시 검은색이어야 하고 시침, 분침은 흰색으로 표시하되 전체영역에 대해 최대 10? 5?%를 넘지 않아야 한다는....그러니까 최소화 해야함)

앰비언트 모드는 디바이스의 배터리를 오래 유지하게 하는데 도움을 줍니다. 이 모드에선 그림자의 회색, 검은색, 흰색만 표시되어야 합니다. 우리의 와치 페이스는 디바이스가 앰비언트모드로 전환될때 노티를 받고 주의깊게 디자인 해야 합니다.



Optimize for Special Screens 

특수 화면에 대해서 최적화 하세요


안드로이드 웨어 디바이스는 여러가지 스크린 기술들로 되어 있습니다. 각각 장점 그리고 고려할 요소들이 있습니다. 앰비언트 모드에 대해 한가지 중요한 고려 요소로 얼마나 배터리 타임(life)에 영향을 주는가, 그리고 스크린 번인이 있습니다.(번인의 경우 OLED를 이야기 하는듯....)


각각의 스크린 종류에 따라 다른 앰비언트 디자인을 할 수 있습니다. 모든 스크린에 대해서 최선의 디자인을 고려하세요.


Low bit

앰비언트 모드에서 몇몇 스크린의 픽셀들은 on 또는 off됩니다. (이렇게 하는것이 low-bit 라 하는듯) 이땐 그레이스케일된 색생을 피하고 오직 흰색, 검은색만을 사용해야 합니다. 그리고 페인트 스타일에서 안티 앨리어싱 모드를 꺼야 합니다. 반드시 테스트 해보세요.


Burn protection techniques

OLED 스크린에 대해서 디자인할때 전력 효율성과 스크린 번인효과를 고려해야 합니다.(역시 번인이 문제...) 스크린이 앰비언트 모드일땐 특정 몇몇 픽셀들이 번인되는것을 막기 위해 시스템이 스크린의 컨텐츠를 주기적으로 쉬프트합니다.(컨텐츠를 상하좌우 조금씩 옮겨 랜더링 한다는 소리) 앰비언트 모드에선 많은 픽셀 블록들을 사용하지 않아야 하고 95%의 픽셀들을 검은색으로 두어야 합니다. 앰비언트 모드에선 솔리드(내부가 채워진) 쉐이프들은 번인을 막기 위해 외곽선으로 바꾸세요. 또한 채워진 이미지들을 픽셀 패턴으로 바꾸세요. 아날로그 와치 페이스에 대해선 침들이 만나는 픽셀 번인을 막기 위해 중앙부분을 비우세요.



Accomodate System UI Elements

시스템 UI 요소를 수용하세요


와치페이스 디자인은 안드로이드 웨어 Ui 요소를 수용해야 합니다. 이 요소들은 유저에게 웨어러블의 상태와 유저의 폰의 서비스에서 오는 노티들을 보여줍니다. UI요소의 방해로부터 와치페이스의 중요한 요소들을 유지하세요.

(보통 웨어 UI 요소들이 하단에 위치하기때문에 되도록 상단 부분 40% 정도에 중요한 요소들을 위치하도록 하는것이 좋을듯 - 또는 UI 요소가 시계를 덮을땐 그 이벤트를 받아 인터렉티브하게 변경하는것도 좋을듯)


Cards

카드는 노티 시스템











저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2014.12.09 11:00

AndroidAnnotations 사용중, 이번 업데이트로 인해 아래와 같은 오류가 뜬다면,



Error:The project is using an unsupported version of the Android Gradle plug-in (0.14.4). The recommended version is 1.0.0.

<a href="fixGradleElements">Fix plugin version and re-import project</a>



apt {

arguments {

androidManifestFile variant.processResources.manifestFile

resourcePackageName "com.flask.testapp"

}

}


에서


apt {

arguments {

androidManifestFile variant.outputs[0].processResources.manifestFile

resourcePackageName "com.flask.testapp"

}

}


ouputs[0]


을 추가해주면 됨

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2014.12.08 16:31

Android unit test 를 작성하면서 retrofit 을 사용하는 서비스가 있어 이를 어떻게 해야 할까를 고민하던중 찾은 방법


Retrofit 에서 비동기로 콜을 하기 위해선 파라미터로 콜백을 넣어주면 되는데 기존에 생각했던 방법으론(when-then) 으론 어떻게 테스트를 해야 할지 의문이었음


방법은 간단하게 when 절 앞에 doAnswer를 넣어주면 됨.



MyApi mock = mock(MyApi.class);


doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Object[] args = invocation.getArguments();

Callback<MyData> callback = (Callback<MyData>) args[0];

callback.success(dummy.myData, null);

return null;

}

}).when(mock).fetchMyData(any(Callback.class));


final DoneMarker doneMarker = new DoneMarker();

mock.fetchMyData(new Callback<MyData>() {

@Override

public void success(MyData myData, Response response) {

assertThat(myData, notNullValue());

assertThat(myData, is(dummy.myData));

doneMarker.done();

}


@Override

public void failure(RetrofitError error) {

fail();

doneMarker.done();

}

});


await().atMost(1, SECONDS).until(doneMarker);



Retrofit 으로 만든 Api 인터페이스의 클래스를 mock 으로 만들고, doAnswer-when 순으로 테스트 코드를 위한 준비 작업을 함.


doAnswer절에선 callback 을 호출해주면 되고, 우리가 테스트 하고자 하는 매서드의 파라미터로는 콜백을 넣어주면 되는데, 모든 콜백을 받기로 하겠다면(모든 콜백을 파라미터로 넣으면, 어떤 콜백이든, doAnswer 절에 정의한 answer가 실행됨) any 를 써서 넣어주면 됨.


그리고 콜백이 비동기로 이뤄지기 때문에(위 코드에선 그렇진 않지만) assertion 을 콜백 내부에서 해준다. 그리고 매서드 호출 마지막에 await() 으로 최대 1초간 doneMarker 가 true 를 리턴할 때까지 기다린다.

* await 은 awaitility 라이브러리의 매서드



저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0


티스토리 툴바