최근에 Sonar를 이용해서 회사에서 만든 안드로이드 앱 소스의 품질을 분석한 적이 있습니다.




나름 잘 만들었다고 생각하고 있었는데 규칙 위반사항이 꽤 많이 검출되어 놀랐었죠. 다행히 중복코드는 없었습니다. Major한 위반사항부터 고쳐나가다가 패키지간 의존성을 없애기 위해 어떻게 하면 좋을까 고민을 많이 했습니다. 단순히 다른 Activity를 명시적으로 클래스명으로 부르지 않고 인텐트필터를 이용해서 부른다고 패키지간 의존성이 명쾌히 해소되지는 않더군요. 

그러다가 EventBus라는 라이브러리를 발견했습니다. 


EventBus 홈페이지

https://github.com/greenrobot/EventBus 


EventBus 사용 예제 설명

http://awalkingcity.com/blog/2013/02/26/productive-android-eventbus/


EventBus 슬라이드 자료

http://www.slideshare.net/greenrobot/eventbus-for-android-15314813


Square에서 만든 Otto라는 원조(?) 라이브러리도 있지만 greenrobot의 EventBus가 왠지 더 땡기더군요. 사용법도 심플하고, 홈페이지에 나오는 Otto와의 비교자료가 마음을 굳히게 만들었죠. (바빠서 직접 비교 테스트는 패스~)


특히나 저희 앱에서는 로그인, 로그아웃 관련해서 단순히 세션을 조작하는데 그치지 않고 앱 내부적으로 다양한 일을 처리합니다. 그래서 로그인 모듈에서 로그인 완료후 다른 모듈들을 직접(!) 호출하는 방식으로 처리하고 있었는데, LoggedInEvent, LoggedOutEvent라는 걸 만들어서 이벤트버스 방식으로 변경했더니 모듈간 의존성도 없어지고 소스도 깔끔해지고 좋네요. 


물론 별별 상황에서 제대로 안정적으로 오류없이 작동하는지는 좀더 지켜봐야겠지만 현재까지는 만족하고 있습니다. 구글링해보면 사실 Otto가 더 많은 레퍼런스와 개발자의 지지를 받는 것으로 보입니다. Square 개발자의 기술력을 신뢰하기 때문으로 보이는데요, 여유가 생기면 Otto로도 재구현해서 테스트해볼 생각입니다. (EventBus의 컨벤션 방식과 비교해서 Otto의 어노테이션 방식도 나름 장점이 있기에...)


아직까지 EventBus 사용하면서 큰 이슈는 없었는데요 이런 점은 고려하셔야 합니다. 


(1) 이벤트를 수신하는 메소드가 컨벤션에 따라서 onEventMainThread(), onEventBackgroundThread() 와 같은 식이어서 만약 상속관계에 있는 클래스에서 동일한 메소드 시그너쳐를 쓴다면 부모 클래스의 메소드를 호출하는 것을 빼먹으면 안됩니다. 이런 경우는 Otto의 어노테이션 방식이 좀더 유연해보입니다.


(2) 이벤트를 어디서 던지고 어디에서 처리할 것인지 아키텍처적으로 정하는 일이 필요해보입니다. 그냥 아무데서나 이벤트 발생시키고 아무데서나 처리하는 것보다는 Presentation 레이어 던지고 처리한다거나, Biz 레이어에서 던지고 처리한다 처럼 어떤 규칙을 정해놓고 개발하는 것이 나을듯합니다.




Posted by 에코지오
,

작년 하반기에 제가 다니는 회사에서 쇼핑 관련된 앱을 하나 만들었습니다. 

사실 대부분의 기능이 웹으로 구현된 터라 실제 네이티브 앱으로 구현된 기능은 별로 없는(?) 편입니다.

그런데도 사용하는 라이브러리가 참 많다는 생각이 드네요.


라이브러리

용도

 대안

Roboguice

객체 의존성 주입, 모듈 생명주기 관리

 AndroidAnnotations, Dagger

AspectJ

에러 처리, 어노테이션 처리 , 아키텍처룰 체크

 

Spring Android (RestTemplate)

REST 통신

 retrofit, restlet

Jackson Json

JSON-Object 매핑

 Gson

Simple Xml

XML-Object 매핑

 

EventBus

모듈간 의존성 제거

 Otto

Spring Security

데이터 암복호화

 

Zbar

QR코드 리더

 zxing

GCMClient

GCM Push 수신

 


Posted by 에코지오
,

앱단에서 서버와 java.net.HttpURLConnection을 이용해서 POST 방식으로 통신하는 경우에 가끔가다 java.io.EOFException 에러가 발생하더군요. 


Caused by: java.io.EOFException

at libcore.io.Streams.readAsciiLine(Streams.java:203)

at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:560)

at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:813)

at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)

at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)

at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:49)

at org.springframework.http.client.SimpleClientHttpResponse.getStatusCode(SimpleClientHttpResponse.java:55)

at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:46)

at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:476)


주로 삼성 갤럭시류의 폰에서 발생하는데, 이 문제 때문에 엄청 골치가 아팠습니다.


구글링해보면 gzip 압축문제 때문이라고 하는 사람도 있고 여러가지 해법이 있었지만 현재까지는 http.keepAlive를 끄는 것이 맞는듯합니다.


public class MyApplication extends Application {

    @Override

    public void onCreate() {

        super.onCreate();

... ...

      

patchEOFException();

        ... ...

    }


    private void patchEOFException() {

        System.setProperty("http.keepAlive", "false");

    }

}



* 참고 사이트

http://stackoverflow.com/questions/13182519/spring-rest-template-usage-causes-eofexception

https://jira.springsource.org/browse/ANDROID-102

http://stackoverflow.com/questions/12280629/nullpointerexception-when-using-spring-resttemplate-in-android

http://android-developers.blogspot.fr/2011/09/androids-http-clients.html

http://stackoverflow.com/questions/3352424/httpurlconnection-openconnection-fails-second-time

Posted by 에코지오
,