FCM으로 업데이트되었다고함..FCM은 추후에 다시 정리하도록 하겠습니다~


Google Cloud Messaging

  • 개발자에게 서버에서 안드로이드 디바스의 어플리케이션으로 데이터를 전송하는 것을 도와주는 무료 서비스.

  • 3rd-party에서 새로운 데이터가 있을 경우 gcm 서비스를 통하여 message를 특정 device의 특정application으로 전송 해준다. message는 최대 4kb

  • GCM 서비스는 message를 큐잉하며 이를 단말에 전달해주는 처리를 담당함.

  • GCM Conntection Server는 http / xmpp 지원함



Flow

  • GCM Server는 3rd-party server로부터 message를 받고 이것을 gcm을 사용하는 app 단으로 전송한다.

  • 현재 GCM connection server는 HTTP와 xmpp를 지원한다.

  • XMPP 프로토콜은 단말과 서버간의 tcp 연결을 계속 유지시켜준다.

  • 3rd-party server는 GCM connection server에 message를 보내고, connection server는 queue에 message를 저장하고, device가 online 일 때 device에 message를 보낸다.

  • app은 GCM message를 받기 위해 GCM에 등록해야하며 , REGISTRATION id를 얻어야 한다.

  • 만약 xmpp conntection server를 사용한다면, client app은 upstream message를 connection server에 보낼 수 있다.



GCM 특징

  • 안드로이드 어플리케이션으로 message를 보낼 수 있는 3rd party server를 허용.

  • GCM은 MESSAGE 전달과 순서를 보장하지 않음.

  • Android Application은 message를 받기 위해 실행되고 있을 필요 없음.

  • GCM은 단순히 원시 DATA를 ANDROID 단말로 보내며, 이 DATA를 통해  application에서 제어함.

  • android 2.2 이상 지원 , Google Play Stote App이 설치되어있어야함.

  • 구글계정 필요, android 4.0.4이상에서는 필요없음.


 

GCM 

서버인증 

 Google Api Console을 통해 발급받은 simple api key를 사용

Sender Id

 Google Api Console을 통해 발급받은 sender ID 사용.

Json Format 

지원 

Multicast message 

동일한 MESSAGE를 여러 단말에 전송할 수 있음.(JSON형태로) 

Multiple Senders 

다양한 3rd party server로부터 같은 app에 message전송.(하나의 통일 restration id사용) 

Time to Live 

0~4주 사이를 expire로 지정가능. 만료일이 지나면 message저장  

battery 

배터리에 좀 더 효율적

quotas 

제한 없음. 



GCM 아키텍처

  • app은 message를 받기위해 GCM으로부터 device를 register함. 이 register를 3rd-party에 등록.

  • 3rd party server는 app에 message를 보내기 위해 등록된 register와 함께 GCM으로 message전송.

  • GCM Connection Server는 register로 확인된 단말에 해당 message를 전송

  1. 단말에서 GCM으로 REGISTER요청
  2. GCM에서 REGISTER 성공 후 resistration id 전송
  3. 3th party server로 registration id 전송
  4. resistration id값과 message를 gcm으로 전송.
  5. 해당 registration에 맞는 단말에 message전송.


GCM 시퀀스



GCM 용어정리

Sender ID

Google API Console로부터 획득한 project number값
Sender ID 값은 GCM에 해당 단말을 register 할 때 사용됨. 이는 GCM으로부터 허가되는 애플리케이션임을 입증하기 위해 사용.

Application ID

Message수신이 설정되어 있는 안드로이드 애플리케이션에게 GCM 서버에 의해 발급된 ID값.
이 값으로 Android 시스템에서 해당 application으로 message를 전송하도록 함.

Registration ID

Message를 수신하도록 허용된 android application에게 GCM 서버에 의해 발급된 ID값.
이 Registration ID값으로 특정 단말의 특정 application과 연결될 수 있는 식별자.

Google User Account

4.0.4 미만 버전에서 GCM이 정상구동되기 위해서 한개 이상의 Google계정이 해당 단말에 설정 되어있어야함.

Sender Auth Token

Message를 보내는 3rd party server에 GCM에 접근이 허용되도록 주어진 API KEY
이 값은 서버에서 GCM으로 전송시 post 요청의 header에 포함되어 있어야함.













'웹 개발 > 안드로이드' 카테고리의 다른 글

RecyclerView란?  (0) 2017.05.10
가변 비트레이트 스트리밍(Adaptive Bitrate Streaming)  (0) 2017.04.11
Parcelable  (0) 2017.04.08
Intent  (0) 2017.03.18
SurfaceView 와 SurfaceHolder  (0) 2017.03.14

Parcelable

앱을 만들다 보면 인텐트를 통해 단순히 기본형 타입의 데이터뿐만아니라, 오브젝트를 다른 컴포넌트에 넘겨줘야할 경우가 많다.  그 경우 단순히 그냥 인텐트에 putExtra()로는 넣어 줄 수가 없다. 안드로이드에서는 그런 경우를 위해 자바의 Serialization 개념과 유사한 Parcelable이라는 클래스가 있다.



위와 같은 Book클래스를 인텐트로 넘겨주려고 하는데, 이대로 사용할 수는 없다.

 오브젝트를 Parcelable 클래스로 만들어주려면 android.os.Parcelable 인터페이스를 구현해야 한다.그러므로 아래와 같이 클래스 정의를 변경한다.



그리고 Parcelable 인터페이스에 있는 2개의 메소드를 오버라이드 해 줘야만 한다.

describeContents() - Parcelable 하려는 오브젝트의 종류를 정의한다.

writeToParcel(Parcel desc,int flags) - 실제 오브젝트 serialization / flattening을 하는 메소드, 오브젝트의 각 멤버변수를 parcel해줘야한다.



다음으로 해야 할 일은 Parcel에서 데이터를 un-marshal / de-serialize하는 단계를 추가해야 한다. 그러기 위해서 Parcelable.Creator 타입의 CREATOR라는 변수를 정의해야 한다. 이 변수를 정의하지 않으면 안드로이드는 다음과 같은 익셉션을 발생한다.

Parcelable protocol requires a Parcelable.Creator object called CREATOR



Book.java 에 모든 parcel된 데이터를 복구하는 생성자를 정의해 줘야만 한다.


주의할 것은 writeToParcel() 메소드에서 기록한 순서와 동일하게 복구해야만 한다.


전체코드는 다음과 같다.


'웹 개발 > 안드로이드' 카테고리의 다른 글

가변 비트레이트 스트리밍(Adaptive Bitrate Streaming)  (0) 2017.04.11
GCM( Google Cloud Messaging ) 이란?  (0) 2017.04.10
Intent  (0) 2017.03.18
SurfaceView 와 SurfaceHolder  (0) 2017.03.14
ANR(Application Not Responding)  (0) 2017.03.14

base64 란 ?

8비트 이진데이터를(예를 들어 실행 파일이나, ZIP파일등..) 공통아스키 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식

왜 사용하는가?

공통된 아스키영역의 문자들만을 사용함으로써 다른 문자코드에 영향을 받지 않음.

인코딩 / 디코딩원리


위에서 말했듯이 Base64 인코딩은 64개의 문자를 이용하여 바이너리 데이터를 공통아스키 영역의 문자들로 변환하는 인코딩 방식이다. 즉 8bit의 데이터(바이너리)를 6bit크기로 표현한다. 따라서 3개의 문자(24bit) 단위를 기준으로 4개의 인코딩된 문자를 얻을 수 있다.



위와같이 abc(24bit)를 base64 방식으로 인코딩하면 YWJj(24bit) 4개의 문자를 얻을 수 있다.


<base64 테이블>


그렇다면 3개(24bit)의 문자단위가 아닐때는 어떻게 될까..?

위의 예시처럼 a(8bit)를 24bit 단위로 표현하면 01100001 0000000 0000000 와 같이 되는데 base64는 6비트단위씩 끊으므로
011000 010000 000000 000000로 변환이 된다.  000000은 A인데 왜 =로 표현되느냐? '='은 bit수를 맞춰주기 위해 0으로 채워주는 패딩값의 표현이다.
즉 문자(바이너리데이터)수가 3n+1이라면 24bit + 8bit인데 24bit단위로 맞춰주기위해 3n(24bit) + 1(8bit) + 16bit를 해주게 되는데, 8bit에서 앞의 6bit는 base64로 인코딩되고 , 남은 2bit와 뒤에 0으로채워진 4bit로 하나의 인코딩된값을 또 얻을 수 있다. 남은 12bit를 2개의 '='으로 채워주게 된다.
즉 3n+1 문자개수라면 '='의 개수가 2개가 되고 , 3n+2 문자개수라면 '='의 개수는 1개가 된다. 


<디코딩의 문제점>

인코딩의 원리는 위와같고, 같은원리로 디코딩역시 YQ== 은 a로 디코딩되는 것을 알 수 있을텐데 여기서 한가지 문제가 발생한다. 인코딩 원리에서 말했듯이 '='이 2개면 3n+1의 문자개수이고 , '='이 1개면 3n+2의 문자개수를 나타낼수 있다.

디코딩 과정에서 '='이 2개면 인코딩된 문자(24bit)중 앞의 8bit만 바이너리 데이터로 변환하고 , 남은 bit는 어떤값이 되던지 신경쓰지 않는다. '='이 1개면 인코딩된 문자(24bit) 중 앞의 16비트만 바이너로 데이터로 변환하고, 마찬가지로 남은 bit값이 어떤값인지 신경쓰지 않는다. 

즉 인코딩된 문자열 YR==,YS==,YT== 등 더있을수있음 디코딩을 해보면 모두 'a'가 나온다.  충돌이 일어날 수 있는 수는 3n+1개의 문자일때는 뒤의 12비트에서 8비트만 정상디코딩이 되고, 남은 4비트가 충돌이 일어나므로 2의 4승인 16개가 생기고 , 3n+2의 문자일때는 2의2승인 4개가 생길것이다.





[출처] http://bbolmin.tistory.com/46




'CS > 개발지식' 카테고리의 다른 글

문자 표현 방식  (0) 2019.02.16
OOP  (0) 2017.03.21
프로세스와 쓰레드의 차이점  (0) 2017.03.20
Runnable 과Thread의 차이  (0) 2017.03.19

직렬화란?

직렬화란 객체를 데이터 스트림으로 만드는 것이다. 즉 객체에 저장된 데이터를 스트림에 쓰기위해 연속적인 데이터로 변환하는 것을 말한다.
 반대로 스트림으로부터 데이터를 읽어서 객체를 만드는 것을 역직렬화라고 한다.
직렬화되는 객체에 대상에는 메소드는 없다. 객체는 클래스에 정의된 인스턴스변수의 집합이다. 객체에는 클래스변수ㅜ나 메서드가 포함되지 않는다. 객체는 오직 인스턴스 변수들로만 구성되어 있다. 그래서 객체를 저장한다는 것은 바로 객체의 모든 인스턴스변수의 값을 저장하는 것이다.


ObjectInputStream , ObjectOutputStream

직렬화에는 ObjectOutputStream , 역직렬화에는 ObjectInputStream을 사용한다.

직렬화가 가능한 클래스를 만드는 방법.

결론부터 말하면 Serializable 인터페이스를 구현하면 된다. 해당 인터페이스에는 구현할 메소드는 없다. 다만 직렬화 가능/불가능을 구별할 수 있도록 하는 인터페이스이다.  하지만 만약 부모클래스에는 Serializable 인터페이스를 구현하지 않았고 , 자식클래스에서는 인터페이스를 구현했을 때, 자식클래스를 직렬화하면 어떻게 될까? 자식클래스에는 부모클래스의 모든 인스턴스 변수가 있지만, 부모클래스가 Serializable 인터페이스를 구현하지 않았기 때문에 부모 클래스의 인스턴스변수는 직렬화에서 제외된다. ( transient 키워드는 임의로 직렬화대상에서 제외시킬 수 있는 키워드)
 따라서 위와같은 경우에는 writeObject와 readObejct 메소드를 정의하여 부모의 인스턴스변수를 직렬화 대상에 직접 추가해줘야한다. 




직렬화 가능한 클래스 버전관리.

직렬화된 객체를 역직렬화할 때는 직렬화 했을 때와 같은 클래스를 사용해야한다. 그러나 클래스의 이름이 같더라도 클래스으 ㅣ내용이 변경된 경우 역직렬화는 실패한다. 객체가 직렬화될 때 정의도니 멤버들의 정보를 이용해서 serialVersionUID라는 클래스의 버전을 자동생성해서 직렬화 내용에 포함한다.그래서 역직렬화 할 때 클래스의 버전을 비교함으로써 직렬화할 떄의 클래스의 버전과 일치하는지 확인할 수 있는 것이다.


serialVersionUID 의 값은 정수값이면 어떤한 값으로도 지정할 수 있지만 서로 다른 클래스간에 같은 값을 갖지 않도록 serialver.exe 를 사용해서 생성하는 것이 보통이다.

컴포지트 패턴

컴포지트 패턴은 간단하게 말해 단일객체든 객체들의 집합이든 같은 방법으로 취급하는 것이다. 다시 말해, 개별적인 객체들과 객체들의 집합간의 처리 방법의 차이가 없을 경우 사용하면 된다. 여시거 컴포지트의 의미는 일부 또는 그룹을 표현하는 객체들을 트리 구조로 구성한다는 것.


UML만드는법을 모른다... 공부해서 수정해야겠다..ㅠㅠ


컴포지트 패턴의 활용

파일시스템을 간단하게 구현해보자. 우선 간단하게 파일 클래스를 만들어보자.
class File{
private String name;
}

그리고 파일을 담을 수 있는 디렉토리 클래스를 만들어보자.
class Directory{
private String name;
private List<File> children;

public void add(File file){
...
}
}


디렉토리 클래스는 자신의 이름과 파일들을 가질 수 있습니다. add() 메소드를 이용해 파일을 추가할 수도 있지요. 근데 이 구조로는 디렉토리 안에 디렉토리가 있는 것을 어떻게 표현해야 할까요?


//파일과 폴더의 근간이 되는 인터페이스.

interface Node{

public String getName();

}


class File implements Node{

private String name();


public String getName(){ return this.name ;}

}


class Directory implement Node{

private String name();

private List<Node> children;


public String getName(){ return this.name; }

public void add(Node node){

children.add(node);

}

}


위와 같은 구조로 변경한다면 폴더안의 폴더를 나타낼 수 있다.



[참조] http://jdm.kr/blog/217

'CS > 디자인패턴' 카테고리의 다른 글

MVC패턴  (0) 2017.03.20

OOP 란?

단 몇 줄로 정리할 수 있는 개념은 아닌 것 같지만, 항상 정의내리기 어려워서 간단하게나마 정리해둠. OOP란 Object-Oriented-Programming의 약어로써, 객체지향 프로그래밍을 의미. 
 유형 또는 무형의 사물(데이터)를 객체로 취급하여 프로그램에 반영한 것이며, 순차적으로 프로그램이 동작하는 기존의 것들과는 다르게 객체와 객체의 상호작용을 통해 프로그램이 동작하는 것을 말한다.
 

OOP의 특징

코드의 재사용성이 높음.
코드의 변경이 용이
직관적인 코드 분석
추상화, 캡슐화, 상속, 다형성


캡슐화

캡슐화는 클래스 내부에 여러 속성과 기능을 함께 묶는 것을 의미하기도 하며, 클래스 내부의 속성이나 기능을 외부에 노출하지 않고 보호하는 것을 의미한다. 즉 여러 속성과 기능을 함께 묶어 클래스로 취급하며, 이러한 클래스 내부를 외부에서 접근하지 못하도록 보호하는 것이다.

why ?

1.클래스 단위로 묶음으로써 프로그램을 바라보는 단위가 커진다. 절차지향언어처럼 함수단위로 구조화하는 것이 아니라, 프로그램 전체를 클래스 단위로 바라볼 수 있게 해준다. 

2.내부의 데이터나 함수를 외부에서 참조하지 못하도록 함으로써 내부의 변경이 자유로워 진다. 외부에 노출되어 많은곳에서 사용 또는 변경된다면 , 클래스 내부의 변경으로 인해 영향가는 곳이 많기 때문이다. 따라서 객체 지향에서는 클래스 내부의 데이터를 외부에서 참조하지 못하도록 차단한다. 내부의 데이터나 함수를 외부에서 참조하지 못하도록 차단하는 개념을 정보은닉이라고 한다. 


추상화

추상화는 객체에서 공통된 속성과 행위를 추출하는 것을 의미한다. 예를 들어, A대학 교수  , B대학 교수 , C대학 교수가 있는데 이들의 공통된 속성과 행위를 교수라는 클래스로 추상화할 수 있다. 

why?

필자의 생각으로는 확장성 때문인 것 같다. 보통 클래스는 설계도라고 비유하고  , 추상클래스는 미완성 설계도라고 비유한다. 미완성 설계도로 제작(객체생성)을 할 수 없지만 공통이 되는 설계도를 가지고 있는 것과 아무것도 없는 상태에서 완성 설계도를 만드는 것은 확연한 차이가 있을 것이다.


상속

클래스의 속성과 오퍼레이션을 하위 클래스에 물려주거나, 상위클래스에서 물려받는 것을 말한다. 

why?

재사용으로 인해 코드가 줄어든다. 상위클래스에 정의되어있는 멤버변수나 메소드를 다시 정의하지 않고 재사용할 수 있으므로, 코드가 줄어든다.

다형성

흔히들 알고있는 부모자료형에 자식자료형을 담는 것이라고 알고있었지만,객체지향에서의 다형성은 '여러 클래스들이 동일한 이름의 오퍼레이션을 서비스하도록 하는 것' 이라고 한다. 후자의 개념에 전자가 포함되는 것 같다. 후자에 의하면 메소드 오버라이딩도 , 메소드 오러로딩도 다형성이다. 

why?

여러타입의 클래스를 하나의 타입으로 관리하니 유지보수가 좋음. 확장성이 좋고, 결합도가 강하지 않은 프로그래밍이 가능하다.

확장성이 좋은이유? 새로운 타입의 클래스를 정의하여도 부모클래스를 상속받거나 or 인터페이스를 구현하여 기능만 추가하면 코드가 변하지 않음.


'CS > 개발지식' 카테고리의 다른 글

문자 표현 방식  (0) 2019.02.16
base64 인코딩/디코딩 원리  (0) 2017.04.04
프로세스와 쓰레드의 차이점  (0) 2017.03.20
Runnable 과Thread의 차이  (0) 2017.03.19

MVC 패턴

사용자의 뷰페이지(View)와 데이터 혹은 비즈니스로직(Model) 그리고 이들 상호간의 흐름제어(Contoller)하는 비즈니스 로직을 분리하여 서로간의 영향없이 모듈을 재사용, 확장 가능한 구조적 패턴. View와 Model을 분리하여 데이터처리 로직이 중복되는 것을 막고, 로직과 Model을 재사용하는데 의의를 둠.
 어플리케이션의 흐름제어나 사용자의 요청처리는 Controller에서 집중처리.


Model = 비즈니스 영역의 상태 정보를 처리.

View = 비즈니스 영역에 대한 뷰를 담당.

Control = 사용자의 입력 및 흐름제어를 담당.



모델1 방식과 MVC패턴의 비교 및 처리절차.

<모델1 방식>


<MVC 방식>


모델1 방식과 MVC방식의 가장 큰 차이점은 컨트롤러 역할을 JSP가 아니라 Servlet에서 한다는 것이다. 모델1방식은 JSP에서 VIEW역할과 Controller역할을 같이 하기 때문에 view코드와 controller코드가 같이 있기때문에 복잡하며 , 로직이 중복되는 문제가 발생함. 이에 반해 MVC 방식은 MVC 각각의 역할이 나


MVC패턴의 문제점 및 대안방안

MVC패턴의 문제점

VIEW와 MODEL 간의 의존성을 완벽히 분리할 수 없는데다 패턴의 모호함때문에 해석이 제각각 달라지며 여러가지 변형이 생김. 

대안방안

MVP(Model,View Interface, Presenter) 패턴에서는 View와 Model의 완벽한 분리가 이루어짐. - MVP에 대해서는 추후 다시 정리.

[출처] http://lefigaro.tistory.com/39


'CS > 디자인패턴' 카테고리의 다른 글

컴포지트 패턴(Composite Pattern)  (0) 2017.03.21

멀티프로세싱 운영체제에서는 동시에 여러 프로그램을 실행할 수 있다. 그때 실행중인 프로그램에 대한 인스턴스를 프로세스라고 한다. 프로세스는 운영체제로부터 주소공간,파일,메모리 등을 할당받는다.


리눅스 시스템에서는 코드 영역과 라이브러리를 프로세스 간에 공유하므로, 메모리 내에 코드와 라이브러리는 하나만 존재한다. 변수에 할당되는 공간으로 데이터 세그먼트와 스택 세그먼트는 프로세스 각각 가지고 있다. 그리고 각 프로세스 마다 실행 위치를 나타내는 PC(Program Counter)도 프로세스별로 관리한다.


스레드란 한 프로세스 내에서 동작되는 여러 실행의 흐름으로, 프로세스 내의 주소 공간이나 자원들을 공유하면서 실행된다.


기본적으로 하나의 프로세스가 생성되면 하나의 스레드가 같이 생성된다. 이를 메인 스레드라고 부르며, 스레드를 추가로 생성하지 않는 한 모든 프로그램 코드는 메인 스레드에서 실행된다. 또한 프로세스는 여러개의 스레드를 가질 수 있으며 이를 멀티 스레드라고 한다.


스레드는 프로세스 내에서 각각의 스택 공간을 제외한 나머지 공간과 시스템 자원을 공유한다. 그러므로 프로세스를 이용하여 동시에 처리하던 일을 스레드로 구현할 경우 메모리 공간은 물론 시스템 자원 소모도 현격히 줄어든다. 스레드간의 통신이 필요한 경우 별도의 자원을 이용하는 것이 아니라 전역 변수의 공간을 이용하여 데이터를 주고 받을 수 있다.


스레드의 장점

시스템의 throughput(처리율)이 향상된다.
시스템의 자원 소모가 줄어든다.
프로그램의 응답시간이 단축된다.
프로세스 간 통신 방법에 비해 스레드 간의 통신 방법이 훨씬 간단하다. 데이터 세그먼트, 즉 전역변수를 이용하여 구현한다.


스레드의 단점

공유하는 전역 변수를 여러 스레드가 함께 사용하려면 충돌 문제가 생길 수 있다. 이러한 문제가 발생하지 않도록 동기화 문제를 해결해야 한다.



'CS > 개발지식' 카테고리의 다른 글

문자 표현 방식  (0) 2019.02.16
base64 인코딩/디코딩 원리  (0) 2017.04.04
OOP  (0) 2017.03.21
Runnable 과Thread의 차이  (0) 2017.03.19

+ Recent posts