반응형

이번 포스팅은 Android에서 화면의 Dp 값을 Pixel로 변환하는 방법에 대하여 알아보도록 하겠습니다. 

Resource r = getResource();

int px = (int) typeValue.applyDimension(TypeValue.COMPLEX_UNIT_DIP, 200, r.getDisplayMetrics());


myEditText.setWidth(px);

반응형

'Development > Android' 카테고리의 다른 글

[Android] Android의 구조  (0) 2016.04.22
[Android] GridLayout  (0) 2016.04.18
[Android] View의 터치영역 넓히기  (0) 2016.03.25
[Android] AsyncTask 중지하기  (0) 2016.03.23
[Android] Intent로 객체 전달하기  (0) 2016.02.12
반응형

이번 포스팅은 View 구성 시 터치 영역을 넓히는 방법에 대하여 알아보도록 하겠습니다.


Layout 구조는 아래와 같습니다.

전체 위젯을 감싸고 있는 test_parent layout 안에 test_view가 들어있는 상황입니다.


위젯의 터치영역이 너무 작아 Layout의 크기만큼 늘리고 싶을 때 아래와같이 touchDelegate를 셋팅해주면 됩니다.

View mTestLayout = rootView.findViewById(R.id.test_parent_layout); ViewGroup.LayoutParams params = mTestLayout.getLayoutParams(); mTestLayout.setTouchDelegate(

new TouchDelegate(

new Rect(0, 0, params.width, params.height),

rootView.findViewById(R.id.test_view)

)

);

위와 같이 구현을 하면 test_parent_layout 영역을 눌러도 test_view의 클릭 리스너가 호출이 됩니다.


View가 MATCH_PARENT이거나 WRAP_CONTENT일 경우, Size가 정확하게 선언되어 있지 않으므로

아래와 같이 OnGlobalLayoutListener에서 처리하는 것도 하나의 방법입니다.

rootView.findViewById(R.id.test_parent_layout).getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() {     @Override     public void onGlobalLayout() {     View mTestLayout = rootView.findViewById(R.id.test_parent_layout);     mTestLayout .setTouchDelegate(

new TouchDelegate(

                    new Rect(0, 0, mTestLayout .getWidth(), mTestLayout .getHeight()),

                    rootView.findViewById(R.id.test_view)

)

          );     } });



반응형

'Development > Android' 카테고리의 다른 글

[Android] GridLayout  (0) 2016.04.18
[Android] dp를 px값으로 변환  (0) 2016.04.14
[Android] AsyncTask 중지하기  (0) 2016.03.23
[Android] Intent로 객체 전달하기  (0) 2016.02.12
[Android] ListView 계층 구조  (0) 2015.08.11
반응형

CDN


콘텐츠 전송 네트워크(Content delivery network 또는 content distribution network (CDN))는 콘텐츠를 효율적으로 전달하기 위해 여러 노드를 가진 네트워크에 데이터를 저장하여 제공하는 시스템을 말합니다. 즉, 지리적으로 여러 개로 분산된 서버를 말합니다. 인터넷 서비스 제공자에 직접 연결되어 데이터를 전송하므로, 콘텐츠 병목을 피할 수 있는 장점이 있습니다.

 

CDN의 목적은 높은 사용성과 효율로 사용자에게 콘텐츠를 전달함에 있습니다. CDN은 오늘날 인터넷에 존재하는 콘텐츠의 상당수를 서비스하고 있는데 이에는 웹 요소 (텍스트, 그래픽, 스크립트), 다운로드 가능한 요소 (미디어 파일, 소프트웨어, 문서), 애플리케이션 (전자상거래, 포털), 실시간 미디어, 주문형 스트리밍, 그리고 소셜 네트워크 등이 있습니다.

 

미디어 회사나 전자상거래 업체와 같은 콘텐츠 제공자는 그들의 콘텐츠를 사용자들에게 전달하기 위해서 CDN 회사에 사용료를 지불한다. 반대로, CDN은 ISP, 이동통신사업자, 그리고 네트워크 사업자들에게 데이터 센터에서의 서버 호스팅 비용을 지불합니다. 더 나은 퍼포먼스와 사용성 이외에도 CDN은 콘텐츠 제공자의 서버의 트래픽을 덜어주어 콘텐츠 제공자의 비용을 줄여줍니다. 추가로, CDN은 대규모 분산 서버 장비로 공격 트래픽을 완화할 수 있으므로 콘텐츠 제공자에게 DoS 공격에 대해서 어느 정도 보호해 줄 수 있습니다. 초기 대부분의 CDN은 CDN이 소유하고 동작하는 서버를 사용하는 콘텐츠만 서비스하였으나 최신 트렌드는 P2P 기술을 이용하는 하이브리드 모델을 사용하는 것입니다. 하이브리드 모델에서 콘텐츠는 지정된 서버 그리고 주변 컴퓨터(peer-user-owned)를 모두 사용합니다.

 

CDN의 사례

인터넷 콘텐츠의 상당 부분이 CDN을 통해 전송됩니다. 간단한 사례를 통해 설명드리겠습니다.
뉴욕에 있는 사용자가 런던에 있는 업체의 웹사이트를 보고 싶어 합니다. 이 웹사이트는 영국의 서버에 호스팅되어 있습니다. 해당 사용자가 뉴욕에서 영국까지 대서양을 가로질러 요청을 보낸다면 웹사이트의 콘텐츠 로딩 시간은 길어질 것입니다. CDN은 이런 문제를 해결하기 위해 런던 웹사이트 콘텐츠를 캐싱해 전 세계 여러 곳의 ‘PoP(Points of Presence)’에 저장합니다. 이러한 PoP는 자체 캐싱 서버를 갖고 있으며 뉴욕에 있는 사용자에게 해당 콘텐츠를 전송합니다.
사용자의 물리적 위치와 가장 가까운 서버에서 전송되는 콘텐츠는 더 빠른 고성능 웹 경험을 제공합니다.

 

CDN의 작용 원리

CDN의 미션은 지연 시간을줄이는 것입니다. 지연 시간은 웹 페이지 또는 비디오 스트리밍 콘텐츠가 디바이스에 완전히 로딩되기 전에 발생하는 불편한 지연을 의미합니다. 지연 시간은 밀리초 단위로 측정됩니다. 하지만 사용자가 체감하는 시간은 매우 길며, 시간 초과 또는 로딩 오류가 발생할 수 있습니다. 콘텐츠가 사용자에게 도달하기 위해 이동해야 하는 물리적 거리를 줄여 지연 시간을 줄이는 콘텐츠 전송 네트워크도 있습니다. 따라서 CDN이 보다 광범위하고 넓게 분산되어 있으면 사용자와 최대한 가까운 곳에 콘텐츠를 배치함으로써 웹 콘텐츠를 보다 빠르고 안정적으로 전송할 수 있습니다.

주말에 최근 개봉한 할리우드 영화를 보고 싶다면 CDN을 통해 해당 비디오를 제공할 최적의 서버를 네트워크에서 찾을 수 있습니다. 이 서버는 일반적으로 사용자의 물리적 위치와 가장 가까운 서버가 됩니다. 미디어 파일은 캐싱되며 동일한 지역의 다른 사용자가 해당 미디어 파일을 요청할 경우에 대비해 콘텐츠 전송 네트워크 서버에 남게 됩니다. 요청한 콘텐츠가 오래되었거나 사용할 수 없는 경우, CDN 서비스는 새로 가져온 콘텐츠를 저장하고 향후 요청에 있을 때 전송합니다.

웹사이트 콘텐츠 전송은 CDN에서 흔히 사용되는 기능이지만, 유일한 기능은 아닙니다. CDN은 4K 및 HD 품질의 비디오, 오디오 스트림, 앱·게임·OS 업데이트와 같은 소프트웨어 다운로드 등 광범위한 콘텐츠를 전송합니다. 즉, 디지털화할 수 있는 모든 데이터를 콘텐츠 전송 네트워크를 통해 전송할 수 있습니다.

 

Reference

1. CDN이란 무엇인가요? | Akamai 참고 자료

반응형

'Development > Terms' 카테고리의 다른 글

[Terms] JWT  (0) 2019.09.11
[Terms] CBOR  (0) 2019.03.12
반응형

이번 포스팅은 AsyncTask를 중간에 중지하는 방법에 대하여 알아보도록 하겠습니다.


  Asynctask변수.cancel(true);


 - 만약 HttpClient를 사용중이라면

       httpClient.getConnectionManager().shutdown();


- 만약 dialog를 사용중이라면 

  dialog의 OnCancelListener 에서 위의 명령어 사용


- onPreExecute() 함수는 Thread로 동작하지 않고, Main Thread에서 동작하는 부분이라서 본문에 넣어 주신 코드 같은 경우는 AsyncTask execute 하는 경우 정상적으로 처리 되었다는 onPostExecure() 콜백 함수가 호출이 됩니다.

- AsyncTask 의 경우 doInBackground() 콜백 함수가 Thread에서 동작하는 부분이며, doInBackground() 가 동작 중에 AsyncTask cancel을 하는 경우  doInBackground() 함수 로직이 완료 된 뒤에 onCancelled() 콜백이 호출이 되도록 되어 있습니다. 


- AsyncTask cancel 을 호출 하지 않은 경우에는 doInBackground() 함수 로직 완료 후 onPostExecure() 콜백이 호출이 되구요. 

@Override
protected Void doInBackground(Void... params) {
    int count = 0;
    while( !isCancelled() && count < 10 ) {
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
              ++count; 
      }
        return null;
}


- AsyncTask에서 위와 같이 doInBackground 를 오버라이드를 하시면 캔슬 하였을 때 onCancelled 콜백이 호출 될꺼에요.


저 AsyncTask의 주요한 세가지 동작에 대해서 알아야 합니다.



1.onPreExecute(): Background 작업 시작전에 UI 작업을 진행을 합니다. 

2.doInBackground(): Background 작업을 진행을 합니다. 

3.onPostExecute(): Background 작업이 끝난 후 UI 작업을 진행합니다. 


- AsyncTask의 숨겨진 문제점 


안드로이드에서 AsyncTask 를 소개할 당시에 ‘문제점 없는 Threading’ 이란 제목이 붙어졌고. 이것은 성공적 인듯 보였지만 완벽 하지 않았습니다. AsyncTask는 UI Thread 와 쉽게 상호 작용 하는 목적을 가지고 있습니다. 하지만 몇몇 경우에서는 AsyncTask는 묘책이 아니에요. 정확하게 알지 못하고, 맹목적으로 AsyncTask를 사용하게 된다면 그 것을 제대로 구현할 수 없습니다. 

또한 문제가 발생될 수 있다. 


문제: 

AyncTask의 목표는 백그라운드에서 UI Thread와의 상호 작용을 쉽게 하는 것이다.

 

그러므로 onPostExecute가 완료 될때까지 많은 UI thread간의 부분적인 업데이트가 실시간으로 이루어집니다. 

화면전환이 일어날 때 이러한 동작은 매우 큰 작업입니다.

 

App 전환이 일어날때 전체의 Activity는 파괴되고, 재생성이 됩니다.

Activity가 재시작 할 때 실행했던 AsyncTask의 reference의 Acitvity는 invalid 하며,  onPostExecute는 새로운 Activity에 아무런 영향을 미치지 못합니다.

 

이것은 AsyncTask의 Activity에 의해 현재 Activity의 잠재적인 referencing에 문제가 발생했다는 것입니다. 



해결: 

보통의 해결책은 속성 변경이나 target Activity의 재시작으로 인한 업데이트를 하는 AsyncTask의 reference 꽉 잡고 있는 것이다.

 

 또다른 다양한 해결 방법은 global holder(전역변수??)를 사용하거나 Activity.onRetainNonConfigurationInstance() 를 사용하는 것입니다. Fragment 에 기초된 시스템을 위해 남은 Fragment들을 AsyncTask에 저장할 수 있습니다. 




- AsyncTask 와 Lifecycle: 

AsyncTask의 dead가 Activity에 원래 이러한 영향을 미치는 것은 아닙니다. AsyncTask는 장시간 사용하면서 문제가 발생합니다.

 

 AyncTask를 예정보다 빨리 종료시키는 방법은 AsyncTask.cancel() 사용하는 방법 뿐입니다.

 

- App의 불필요한 백그라운드 tasking 이나 메모리 누수를 막기 위해서는 cancel을 잘 사용 해야 합니다. 


Cancelling AsyncTasks: 

검색 쿼리를 AsyncTask에서 실행해야 한다고 가정합니다. 유저는 검색 파라미터를 AsyncTask가 동작하는 동안 변경하기를 원하고, 그래서 AsyncTask.cancel()을 호출하고 새로운 AsyncTask를 호출했습니다. AsyncTask 완료되었는지 고려하지 않고 cancel을 하거나 그렇지 않을 것입니다. 이것은 mayInterruptIfRunning(실행중인 작업을 취소) 를 하게 될 것입니다. 

무슨 일이 일어나고 있는 것일까요? 



문제는 AsyncTask.cancel() 에 관한 잘못된 개념에 있습니다. 

AsyncTask.cancel() 은 결과를 고려하지 않고 thread를 죽이지 않습니다. 모든 동작은 “취소된” 상태입니다. 

당신이 동작을 중단하기 위해 Asynctask를 취소된 상태로 만들지 만들지는 당신이 알아서 확인 해야 합니다. 




그러므로 두 가지 간단한 솔루션이 있습니다. 

AsyncTask.isCancelled() 을 오랫동안 동작 중일때 확인하거나 thread를 중단을 계속해서 시키는 것입니다. 둘 중 어느 쪽이든 AsyncTask.cancel()을 호출하는 것은 필요한 시간보다 더 많은 시간의 동작을 멈추게 된다. 



앞서 말햇던 것들이 항상은 아니지만 오랜 시간 동안 메소드를 호출한다면 중단 할 수 없습니다. (BitmapFactory.decodeStream()) 이런 상황은 exception이 발생합니다. 

cancel()이 문제 해결책의 전부는 아니다. 




AsynTask의 동시성 한계 

저는 사람들에게 백개의 백그라운드 thread를 돌리도록 권유하지 않습니다. 시작 할 수 있는 AsyncTasks의 숫자를 제한하는 것은 가치 없는 일입니다. 현재 AsyncTask 는 128개의 동시성 task로 제한 되어 있습니다. 큐는 10개의 task로 제한 되어 있습니다. 138개의 task보다 많은 일을 이것들이 완료되기 전에 한다면 당신의 Application은 망가질 것입니다. 저는 Bitmap을 net으로부터 받아오는 과정에서 이런 일이 발생하는 것은 본적 있습니다.

모든 것들이 한번에 실행되지 않도록 백그라운드의 Task들의 갯수를 잘 조절하고. 디자인하며 pool 사이즈를 code스스로 적용되도록 해야 할 것입니다. 




출처 : http://logc.at/2011/11/08/the-hidden-pitfalls-of-asynctask/ 


반응형
반응형

이번 포스팅에서는 객체를 Intent를 통해 전달하는 방법을 알아보겠습니다. 


정수같은 단순한 값은 크기도 작고 접근 속도도 빨라 저장하고 복귀하기 쉽습니다. 그러나 단일 값이 아닌 큰 객체나 배열을 저장할 때는 최대한 신속하게 저장하기 위해 좀 더 효율적으로 데이터 처리를 해야 합니다. 


객체를 저장할 때는 자바의 Serialize 기능을 사용하면 쉽게 구현할 수 있습니다. 자바는 언어 차원에서 객체를 일차원의 데이터로 저장하는 기능을 제공하는데 이 기능이 바로 Serialize 입니다. Serializable 인터페이스를 상속 받으면 디폴트 직렬화 알고리즘이 적용되어 클래스의 모든 인스턴스 필드가 순서대로 저장이 됩니다. 


1. 먼저 Intent로 전달한 객체에 Serializable 인터페이스를 상속 받습니다. 

   아래 그림처럼 빨간 네모 박스가 Serializable 인터페이스를 상속받은 구현방법입니다.



2. Serializable 인터페이스를 상속받은 객체를 Intent에 담아 전달 받을 클래스로 보냅니다.

   (※ Intent로 전달하기 전에 전달 받은 클래스가 AndroidManifest.xml에 등록이 되어 있어야 합니다.)



3. Intent를 전달받은 클래스에서는 getSerialzableExtra() 메소드로 불러오기만 하면 됩니다. 



- 아래는 결과 값인 Logcat 메시지 입니다.


참 간단하죠? 예제 소스를 압축 파일로 올려 놓았으니 필요하신 분들은 다운받아 실행해 보시면 좀 더 이해하기 쉬우실 것 같습니다. 

다음에 알차고 좋은 내용으로 찾아 뵙겠습니다.


SerializableExam.zip


반응형
반응형

이번 시간에는 우리가 가장 많이 쓰는 ListView의 계층 구조에 대해 알아보겠습니다. 


- 먼저 ListView에 대해 알아보도록 하겠습니다. 

   ListView는 여러개의 항목을 수직으로 표시하는 위젯입니다. 

   수직 스크롤을 지원하므로 항목의 개수가 아무리 많아도 모두 표시할 수 있는 장점이 있습니다.


- ListView의 계층 구조를 먼저 그림으로 알아보도록 하겠습니다.




- 안드로이드 개발을 할 때 ListView, GridView, Spinner, Gallary 를 오버라이딩 해서 UI를 구성하는 경우가 많이 있습니다. 

  이들을 묶어서 AdapterView라고 부르며 집합을 화면에 표시한다는 면에서 기능적으로 동일합니다.


- 이 위젯들을 AdapterView 라고 부르는 이유는 표시할 항목 데이터를 직접 관리하지 않고 Adapter 객체로부터 공급받기 때문입니다. 즉, Adapter 객체는 원본으로부터 얻은 데이터를 관리하며 AdapterView는 Adapter가 전달한 데이터를 화면에 표시하는 식으로 분업화 합니다.


- 그림으로 도식화하면 아래와 같습니다.




- 그럼 데이터를 담당하는 Adapter 계층 구조를 살펴보도록 하겠습니다.




- 최상위 Adapter 인터페이스는 AdapterView와 데이터간의 연결을 제공하고 항목의 집합을 관리하는 기본적인 메서드를 선언합니다. 그리고 BaseAdapter는 상위 객체인 ListAdapter와 SpinnerAdapter의 공통적인 기능을 구현합니다. BaseAdapter의 getView 메소드를 오버라이딩 하여 화면을 구성하게 됩니다.


- BaseAdapter의 하위 객체는 데이터의 원본에 따라 나뉘어 집니다. ArrayAdapter는 배열이나 리소스에 정의된 배열로부터 데이터를 가져오며 CursorAdapter는 데이터베이스로부터 데이터를 가져오며 SimpleAdapter는 XML 파일의 정적인 데이터를 원본으로 가져옵니다.


이번 시간에는 Adapter와 AdapterView 의 유기적인 관계와 각 객체의 계층구조를 알아보았습니다. 

다음 시간에는 좀 더 자세한 구현 방법에 대해 알아보도록 하겠습니다.


반응형

+ Recent posts