월별 글 목록: 2011년 11월월

JSON Validator/Formatter 사이트들..

JSON 포맷으로 데이터를 주고 받는 서버나 클라이언트 혹은 앱을 개발하다 보면, 보내고 받은 데이터의 포맷이 맞는지 그리고 받은 데이터를 디버깅하기 위해서 포맷팅을 해서 가독성있게 바꾸는 작업을 빈번하게 하게 됩니다.. 이 때, 프로그램상에서 로그나 콘솔에 포맷팅을 해서 가독성있게 보여줄 수 있겠지만, 여간 불편한게 아니죠.. 

보통, 웹 서버를 통해서 JSON 데이터를 받게되면, 스트림으로 주~욱 받게 됩니다.. 그러면, byte[]로 받아서 String으로 변환을 해서 포맷팅을 하든, 아파치 HTTPClient같은 넘을 사용해서 결과로 String을 받아오든지 합니다..

결국, 다시 한번 String을 포맷팅을 해야 가독성이 생기게 됩니다.. 그래서, 받은 String 데이터를 Validate와 Formatting을 해주는 사이트를 찾아서 받은 String 데이터를 넣어서 포맷팅된 JSON으로 보게 되네요..

그래서, 유용한 사이트를 몇개 정리해 봅니다..

1. http://www.freeformatter.com/
 지원하는 Formatter와 Validator는 아래와 같이 매우 다양합니다.. 매우 다양한 포맷을 지원하기 때문에 개발하면서 매우 유용한 사이트가 될 것 같습니다..
 – JSON Formatter & Validator :

 – HTML Formatter & Validator :
 – XML Formatter :
 – SQL Formatter :
 – String Escaper :
 – Url Encoder / Url Decoder :
 – Base 64 Encoder / Base 64 Decoder :
 – JavaScript Minifier – Online YUI Compressor for JavaScript :
 – CSS Minifier – Online YUI Compressor for CSS : 

 – Message Digest : 

2. http://jsonlint.com/
 JSON Formatter와 Validator로 가장 유명할 것으로 생각이 드는 사이트 입니다..
 
3. http://jsonformat.com/
 JSON Formatter와 Validator를 지원하고 있고, 추가적으로 HTML Formatter도 지원하고 있네요.. 

4. http://jsonformatter.curiousconcept.com/
 JSON Formatter와 Validator를 지원합니다.. 

위의 사이트중 한개만 즐겨찾기 해 놓으면, JSON 포맷 기반의 프로젝트 하기에 편할 것으로 생각이 듭니다..

안드로이드(Android) 기기의 다양한 화면 지원하기

안드로이드(Android) OS는 다양한 기기에 포팅될 수 있다. 그리고 다양한 기기는 자신만의 화면 크기를 가지는 경우가 많다. 이렇다 보니 애플리케이션을 개발하다 보면 기기의 고유 해상도로 인해서 문제가 생길 수 있다.

안드로이드는 허니콤 버전부터 태블릿을 지원하기 시작해서, 아이스크림부터는 모바일과 태블릿을 같이 지원하기 시작했다. 이런 상황이다 보니, 구글에서는 해상도에 어울리게 UI를 구성(XML 파일로 구성)하도록 가이드(Supporting Multiple Screens) 하고 있다. 이 가이드를 보면 다양한 해상도를 지원하려면 /res/layout-sw600dp/layout.xml 과 같은 파일을 화면에 적합하게 여러 개 만들어서 개발하라는 것이다.

화면에 적당한 UI로 앱의 퀄리티를 유지하는 방향으로는 좋겠지만, 그만큼 개발비용(iOS에 비해)을 증가시킬 게 분명하다. 물론, 이 방법으로 한 바이너리로 모바일/태블릿/TV를 지원할 수 있어서 좋긴 하다. 하지만 가이드 대로 개발해 보니, 이렇게 분리해서 개별 UI(모바일/태블릿/TV)의 장점을 살릴 수 있을까? 라는 질문에는 잘 만들면(?) 된다는 생각이다. 한 바이너리로 여러 화면에 적합한 UI를 서비스 할 수 있다는 것은 역시나 매력적이고 앞으로도 이 방향으로 서비스를 개발하는 것이 좋겠다.

앱을 개발하면서 화면별(모바일, 태블릿 그리고 TV) UI 구성은 어떻게 할 수 있을까? 에 대한 대답은 layout_weight 속성으로 해결한다는 것이다.

아래 예제에서 <LinearLayout>의 layout_weight 속성을 가지는 요소는 자신의 UI가 차지하는 %를 숫자(6 -> 60%)로 표현한 것이고, weightSum은 없으면 알아서 배열하지만, 아래 예에서는 10으로 입력해 놓았다. 그리고 가로(horizontal) 또는 세로(vertical)의 비율로 크기를 맞추는 방법은, 가로를 맞추기 위해서는 layout_width, 세로로 맞추기 위해서는 layout_height을 ‘0dp’로 입력하면 된다.

아래는 위에서 설명한 화면의 구성을 비율로 구성한 예이다.

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    android:id=”@+id/linearLayout”
    android:orientation=”horizontal”
    android:layout_width=”fill_parent”
    android:background=”#568dfb”
    android:weightSum=”10.0″
    android:layout_gravity=”center_vertical”
    android:layout_height=”40dp”>

    <TextView android:id=”@+id/textView”
        android:text=” “
        android:visibility=”visible”
        android:paddingLeft=”8dp”
        android:layout_width=”0dp”
        android:layout_weight=”6″
        android:textColor=”@android:color/white”
        android:layout_height=”40dp”
        android:textAppearance=”?android:attr/textAppearanceMedium”/>

       <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
        android:id=”@+id/linear_container”
        android:orientation=”horizontal”
        android:layout_width=”0dp”
        android:layout_height=”40dp”
        android:layout_weight=”4″
        android:background=”#568dfb”
        android:gravity=”right”
        android:layout_gravity=”center_vertical”>
       
        <ProgressBar
            android:layout_gravity=”right|center_vertical”
            android:background=”#568dfb”
            android:layout_width=”30dp”
            android:layout_height=”30dp” />
       
        <TextView
            android:id=”@+id/loadingTextView”
            android:layout_width=”wrap_content”
            android:layout_height=”40dp”
            android:layout_gravity=”right”
            android:background=”#568dfb”
            android:gravity=”center_vertical”
            android:paddingLeft=”4dp”
            android:paddingRight=”4dp”
            android:text=”Loading…”
            android:textAppearance=”?android:attr/textAppearanceMedium”
            android:textColor=”@android:color/white”/>
    </LinearLayout>
</LinearLayout>

 

안드로이드(Android) 페이스북(Facebook) SDK 사용하기

안드로이드(Android) 앱에서 페이스북(Facebook) SDK를 사용하는 내용이다. 아래는 페이스북 SDK를 연동하면서 정리한 내용이고 이클립스를 기준으로 설명한다.

1.  https://github.com/facebook/facebook-android-sdk 다운로드 및 압축해제
1.1. 압축을 해제한 프로젝트에서 facebook 폴더의 프로젝트를 이클립스에 import 한다.

 

 1.2 기존의 프로젝트에 reference 하기
– Project > Properties > Android > Library > Add로 com_facebook_sdk를 추가한다.

  

2. OpenSSL 설치
2.1. 리눅스 설치 : http://www.ibrtses.com/linux/openssl.html
2.2. 윈도 설치 : http://www.slproweb.com/products/Win32OpenSSL.html 에서 환경에 맞게 설치를 한다. 혹, bin 디렉토리가 PATH에 안 잡혀 있어서 페이스북에 등록해야 하는 해시키 생성에 실패할 수 있으니 확인이 필요하다.

3. 해시키 만들고 등록하기
3.1 해시키 만들기 : 아래의 명령을 통해서 해시키를 만든다.
> keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
3.2 만들어진 해시키를 페이스북에 등록한다.
Facebook Developer 페이지의 Step 5의 이미지를 보면 쉽게 확인할 수 있다.

4. 테스트 하기..
테스트 코드도 역시 Facebook Developer 페이지에서 확인하면 된다.

* Reference
Facebook Developer 페이지

데이터 포맷별 성능 비교자료..

많은 서비스들의 자사의 서비스를 오픈하고 있고, 이 오픈된 API들은 프로토콜이라 부르는 데이터 전송 포맷을 사용한다. 현재 매우 많은 데이터 포맷이 존재하고 있고, 목적에 의해서 계속 생겨나고 있다. 따라서, 네트웍을 사용하는 시스템이나 서비스를 개발하는 경우, 네트웍으로 전송하는 데이터 포맷이 전체적인 성능이나 유연성을 좌우하는 매우 중요한 요인이 되었다.

그래서, 데이터 포맷별로 성능 테스트한 자료를 정리해 봤다.

1. Java Serialize Benchmarking
– 이 테스트 자료는 자바환경에서 https://github.com/eishay/jvm-serializers 프로젝트에서 테스트한 자료이다.
– 테스트 결과중에 성능에 대한 차트만 첨부를 했다. 예전의 테스트 자료에서는 kryo가 protobuf보다 더 빠른 결과가 나왔었는데, 2011-07-13일 버전의 테스트 자료에서는 역전을 했네요.. ^^ 그리고, 위의 테스트 결과 위키에서의 답글(2011-10-27)을 보면, 테스트 결과에서는 kyro가 상당히 의미있는 결과를 보여주고 있네요..
– 이 테스트 자료는 상당히 방대한 자료에 대한 테스트를 진행했기 때문에 정말 고마운 자료이다. 그래서, 꼭 자세히 살펴볼 필요가 있다. 하지만, 최근(?)에 사용을 늘려가고 있는 MessagePack과 YAML에 대한 자료가 없는건 아쉬운 점이다.

– 테스트한 결과에 대한 스냅샷을 위해서 .mht 파일로 첨부했다.
java seriliazers benchmarks(2011-07-13).mht

2. MessagePack에 대해서 고려한 카산드라..
– 카산드라 0.7버전에서 MessagePack을 thrift의 대안으로 고려를 했었다. 물론 카산드라 버전에서 MessagePack 라이브러리를 살펴볼 수 없기 때문에 채택이 안된건 확실하다. 카산드라 JIRA CASSANDRA-1735에서 카산드라 프로젝트의 의장인 Jonathan Ellis의 코멘트를 보면, 의미가 없었다고 한다.

Gary did some tests in CASSANDRA-1765 and found no significant advantage over Thrift. Given that, and our brief experience supporting a second rpc protocol (Avro in the 0.7 series), I don’t think this is going anywhere.

– JIRA에서 살펴보면, 테스트 결과는 꽤 성능향상 이점(random read 15%, random write 21%)이 있어 보이긴 한다. 흠.. 위의 Jonathan Ellis의 코멘트가 사실이라면, 역시 테스트는 데이타에 따라 결과에 대한 차이가 나오지 않았을까 추측해 본다.

Performance improvement available with this patch will be the following:

  • Reducing serialization cost and the data size
  • Increase throughput between clients and a Cassandra node

I have also measured the performance of MessagePack, from the viewpoints of reducing serialization cost and throughput. I will discuss details below.

== Reduction of serialization cost and the data size ==
(Summary)
MessagePack has proved to be better in reducing serialzation cost and the data size compared to other serialization libraries in the test below.

(Test environment)
I used “jvm-serializers” which is a well-known benchmark and compared performances with Protocol Buffers, Thrift, and Avro. Machine used for this benchmark has Core2 Duo 2GHz with 1GB RAM.

(Results)
create  ser +same deser +shal +deep total size +dfl
protobuf    683 6016 2973  3338  3454 3759 9775 239 149
thrift      572 6287 5565  3479  3616 3770 10057 349 197
msgpack    291 4935 4750  3468  3545 3708 8748 236 150
avro     2698 6409 3623  7480  9301 10481 16890 221 133

(Comments)
It may be better to compare serialization cost using objects with Cassandra like a Column object. But such objects and sizes vary by users, and is not suitable for comparing serialization cost of various data. According to the above result, the size of MessagePack’s serialized data is slightly larger than Avro. But MessagePack has significantly low serialization cost compared to Avro and Thrift.

== Increasing throughput ==
(Summary)
I compared MessagePack based RPC of Cassandra to that of Thrift. Random read throughput of MessagePack based RPC is 15% higher than that of Thrift and random write throughput is 21% higher.

(Test environment)
In this evaluation, Cassandra node ran as a standalone on a machine with Core2 Duo 2GHz and 1GB RAM. Client programs ran on two machines both with Core2 Duo 2GHz and 1GB RAM. Client program was based on ring cache. It created 100 threads per a JVM on each machine and accesses to a Cassandra node with ring cache.

(Results)

  • Thrift based RPC part of Cassandra(read: 5,200 query/sec., write: 11,200 query/sec.)
  • MessagePack based RPC part of Cassandra (read: 6,000 query/sec., write: 13,600 query/sec.)

(Comments)
I measured the max throughput of random access (read/write) after 100 items (size of each item is small) were stored in the Cassandra node. The reason is because I wanted to make the state of CPU bottle neck for the Cassandra node. If the Cassandra node is the state of Disk IO bottle neck, I thought that I cannot properly evaluate max throughput of the RPC part.

I did not measure the amount of data transferred in network during the evaluation directly. But from the benchmark result of jvm-serializers, I believe that the amount of transferred data for MessagePack-based Cassandra would be reduced compared to that of Thrift.

3. Serializing data speed comparison: Marshal vs. JSON vs. Eval vs. YAML
– 이 테스트 자료는 루비로 테스트를 했다고 한다.

Last night at the NYC Ruby hackfest, I got into a discussion about serializing data. Brian mentioned the Marshal library to me, which for some reason had completely escaped my attention until last night. He said it was wicked fast so we decided to run a quick benchmark comparison.

The test data is designed to roughly approximate what my stored classifier data will look like. The different methods we decided to benchmark were Marshal, json, eval, and yaml. With each one we took the in-memory object and serialized it and then read it back in. With eval we had to convert the object to ruby code to serialize it then run eval against that. Here are the results for 100 iterations on a 10k element array and a hash with 10k key/value pairs run on my Macbook Pro 2.4 GHz Core 2 Duo:
user      system     total       realarray marshal  0.210000   0.010000   0.220000 (  0.220701)array json     2.180000   0.050000   2.230000 (  2.288489)array eval     2.090000   0.060000   2.150000 (  2.240443)array yaml    26.650000   0.350000  27.000000 ( 27.810609)
hash marshal   2.000000   0.050000   2.050000 (  2.114950)hash json      3.700000   0.060000   3.760000 (  3.881716)hash eval      5.370000   0.140000   5.510000 (  6.117947)hash yaml     68.220000   0.870000  69.090000 ( 72.370784)
The order in which I tested them is pretty much the order in which they ranked for speed. Marshal was amazingly fast. JSON and eval came out roughly equal on the array with eval trailing quite a bit for the hash. Yaml was just slow as all hell. A note on the json: I used the 1.1.3 library which uses c to parse. I assume it would be quite a bit slower if I used the pure ruby implementation. Here’s a gist of the benchmark code if you’re curious and want to run it yourself.

If you’re serializing user data, be super careful about using eval. It’s probably best to avoid it completely. Finally, just for fun I took yaml out (it was too slow) and ran the benchmark again with 1k iterations:
user      system     total       realarray marshal  2.080000   0.110000   2.190000 (  2.242235)array json    21.860000   0.500000  22.360000 ( 23.052403)array eval    20.730000   0.570000  21.300000 ( 21.992454)
hash marshal  19.510000   0.500000  20.010000 ( 20.794111)hash json     39.770000   0.670000  40.440000 ( 41.689297)hash eval     51.410000   1.290000  52.700000 ( 54.155711)

시스템을 설계하면서 네트웍으로 데이터를 전송/수신하기 위한 포맷은 위의 자료로 대부분 살펴본 것 같다. 개발하는 시스템의 성격에 따라서 속도와 사이즈 어떤 것이 중요할지는 개발자의 판단이고, 이 포스팅이 도움이 되었으면 좋겠네요. ^^

android.view.WindowLeaked 문제에 대한 해결책..

진저브레드(안드로이드 2.3) 부터는 태스크를 처리하는 형태로 AsyncTask를 사용하도록 가이드 하고 있다. 이 클래스를 사용하다 보면, 자주는 아니지만 가끔 android.view.WindowLeaked 에러를 발생시킨다. 이런 경우에 이 클래스(AsyncTask)를 생성해서 실행시킨 Activity가 onPuase()나 onClose() 상태가 되면서 finish되는 상태가 되고, 이 상태에서 AsyncTask의 결과를 처리하는 스레드(UI 스레드)가 아직 실행 중인 상태에서 발생한다. 즉, Context 객체를 AsyncTask에서 사용하는 중에 Context 객체가 종료돼서 발생한다. 그래서, 간단한 해결책을 살펴보자.

Dialog 클래스 류의 작업을 보통 AsyncTask로 많이 구동시키는데..

1. Dialog를 클래스 변수로 선언을 한다.

private ProgressDialog dialog;
private Dialog d;

2. 별도 쓰레드에서 클래스 변수를 인스턴스화해서 사용하자.

dialog = ProgressDialogFactory.create(AAAActivity.this, false);

3. Activity의 onPause나 onClose같은 상황이 되서 Activity가 finish되는 상황에서 dialog를 종료해 주자.

if (dialog != null && dialog.isShowing()) {
  dialog.dismiss();
  dialog = null;
}
  
if(d != null && d.isShowing()) {
  d.dismiss();
  d = null;
}

finish();

위 형태로 Dialog를 사용하면 android.view.WindowLeaked 문제는 쉽게 해결된다. ^^