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

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

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


라이브러리

용도

 대안

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 수신

 


신고
크리에이티브 커먼즈 라이선스
Creative Commons License
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

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 에코지오

댓글을 달아 주세요

꼭 안드로이드일 필요는 없지만, AspectJ를 통해서 아키텍처 규칙 위반사항을 체크하는 예제를 공유합니다.

(제가 다니는 회사에서 적용 중인 애스팩트를 살짝 수정한 것입니다)


import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import android.app.Activity;


/**

 * 아키텍처 규칙 위반을 체크하는 애스펙트.

 */

@Aspect

public class ArchitectureRuleCheckAspect {

    private static final String PREFIX = "[아키텍처 규칙위반]";


    //공통 액티비티(하위 액티비티)가 아닌 곳에 선언된 메소드 실행시

    @Pointcut("!within(com.mycompany.xxx.BaseActivity+) && execution(* *(..))")

    private void notInBaseActivity() {

    }


    @DeclareError("@annotation(com.mycompany.xxx.Click) && notInBaseActivity()")

    static final String useClickAnnotationOnlyInBaseActivity = "@Click 어노테이션은 BaseActivity 하위클래스의 메소드에만 적용할 수 있습니다.";


    @DeclareError("call((@com.google.inject.Singleton *).new(..))")

    static final String dontCreateSingletonDirectly = "@Singleton 클래스 인스턴스를 직접 생성하면 안됩니다. @Inject를 사용하세요.";


    @DeclareError("within(com.mycompany.xxx.Controller+) && call(com.mycompany.xxx.Controller+.new(..)) ")

    static final String dontUseAnotherControllerInControllers = PREFIX + "콘트롤러에서 다른 콘트롤러를 사용할 수 없습니다.";


    @DeclareError("call(* com.mycompany.xxx.Controller+.*(..)) && (within(*..*Action) || within(*..*Connector)) ")

    static final String useControllerOnlyInPresentationLayer = PREFIX + "콘트롤러는 프리젠테이션 레이어에서 사용해야합니다.";


    @DeclareError("within(*..*Connector) && call(* *.*Action.*(..)) ")

    static final String dontCallActionInConnectors = PREFIX + "커넥터 레이어에서는 비즈니스 레이어(액션)를 호출할 수 없습니다.";


    @DeclareError("call(* android.app.Activity+.*(..)) && (within(*..*Action) || within(*..*Connector)) ")

    static final String useActivityOnlyInPresentationLayer = PREFIX + "액티비티는 프리젠테이션 레이어에서 사용해야합니다.";


    @DeclareError("@annotation(com.mycompany.xxx.Rest) && !within(*..*Connector) ")

    static final String useRestAnnotationOnlyInConnectors = PREFIX + "@Rest 어노테이션은 커넥터 레이어에서만 사용할 수 있습니다.";


}


저의 경우 앱 개발시에 레이어 구조와 MVC 패턴을 적용한 아키텍처 표준을 정해놓고 개발합니다.

레이어 구조는 Presentation(Activity) -> Business(Action) -> Connector(Connector)가 되고, 

MVC패턴은 Presentation 레이어에 적용됩니다.


위 애스펙트 예제는 이러한  아키텍처 상에서 레이어간 역참조 및 MVC 담당 모듈을 엉뚱한 레이어에서 사용하는 것을 방지하고 있습니다.


아키텍처 표준뿐 아니라 자체 제작한 유틸리티 어노테이션을 올바른 곳에서 사용하고 있는지 체크하는 규칙을 포함하며, 

Injection에 의해 주입받아야할 컴포넌트를 직접 instance화하는지도 검사합니다.




신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 에코지오

댓글을 달아 주세요



티스토리 툴바