일단 공식 홈페이지는 아래와 같다.

 

http://www.android-x86.org/

 

초기에 비하면 꽤 많은 진척이 있는 것 같다.

Virtual Box로도 동작 확인이 가능하며, Eclair, Froyo, Ginger-Bread 까지 빠르게 포팅 작업이 이루어 지고 있는 것 같다.

 

테스트 플랫폼도 EeePC, Samsung Q1U, Viliv S5, Lenovo ThinkPad x61 Tablet, ViewSonic ViewPad 10 등이 있다.

 

넷북에서의 사용을 목적으로 하기 때문에 기존 안드로이드와 다르게 추가된 내용은 다음과 같다.

 

- Wifi 와 Ethernet 지원

- Mouse cursor/wheel 지원

- native resolution 지원 (800x480 과 1024x600 지원)

- Proxy setting 지원

- Mplayer 포팅

- External storage auto mount support (Virtual Box로는 아무 변화가 없는 듯)

- External monitor support (해야하는 일로 되어 있어서 좀 더 확인해 봐야 할듯)

 

Virtual Box로는 OpenGL 지원이 제대로 되는지 모르겠다. Live Wallpaper 설정시, 일부는 정상 동작하고 일부는 동작이 조금 이상하게 나온다.

 

Atom 기반으로 되어 있기 때문에 최적화나 시스템 부하는 고려하지 않는 점이 있어서 ARM 기반으로 포팅시에는 주의가 필요하다.

 

코드 받으려면 다음과 같이 한다.

 

$repo init –u git://git.android-x86.org/manifest.git –b $branch
$repo sync

 

branch 명은 donut-x86, eclair-x86, froyo-x86, gingerbread-x86 이다.

오늘 해 볼 작업은 WebView 입니다. 웹기반 어플리케이션이라고 보면 되고 완성될 화면은 아래와 같습니다.

Daum의 모바일 웹페이지 프론트 페이지입니다. 맨 아래 하단에는 버튼을 두어서 원하는 곳으로 이동도 해 볼 겁니다.


 

Daum의 모바일용 웹페이지를 호출한 화면입니다.

웹브라우져 객체를 담기 위해 webview 를 아래 버튼을 만들기 위해 button 을 이용합니다.



1. 프로젝트 생성
 HelloWebView



2. Main.xml 코딩

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
 
 <LinearLayout
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:layout_weight="1">
 
  <WebView
  android:id="@+id/webview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"/>
 
 </LinearLayout>
 
 <LinearLayout
 android:orientation="horizontal"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:layout_weight="8">
 
  <Button
  android:id="@+id/Button01"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Home"
  android:layout_weight="1"
  android:textSize="8pt"/>
 
   <Button
   android:id="@+id/Button02"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Portal"
  android:layout_weight="1"
  android:textSize="8pt"/>
 
   <Button
   android:id="@+id/Button03"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Close"
  android:layout_weight="1"
  android:textSize="8pt"/>
 
 </LinearLayout>
 
</LinearLayout>

위 처럼 코딩 하시면 화면 구성은 끝납니다. 화면에 구성에 필요한 부분은 별도로 공부 하시면 도움이 많이 될겁니다. 별도로 포스트 할 예정입니다.



3. HellowWebView.java 코딩

package com.sample.HelloWebView;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;

public class HelloWebView extends Activity {
 private static final String URL1="http://m.daum.net/mini";
 private static final String URL2="http://m.naver.com";
 WebView webview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        webview = (WebView) findViewById(R.id.webview);
        webview.getSettings().setJavaScriptEnabled(true);
        webview.loadUrl(URL1);

       
        webview.setWebViewClient(new HelloWebViewClient());
       
        Button b1 = (Button)findViewById(R.id.Button01);
        Button b2 = (Button)findViewById(R.id.Button02);
        Button b3 = (Button)findViewById(R.id.Button03);
       
        b1.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
          webview = (WebView) findViewById(R.id.webview);
          webview.getSettings().setJavaScriptEnabled(true);
          webview.loadUrl(URL1);
          webview.setWebViewClient(new HelloWebViewClient());
   }
  });
       
        b2.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
          webview = (WebView) findViewById(R.id.webview);
          webview.getSettings().setJavaScriptEnabled(true);
          webview.loadUrl(URL2);
          webview.setWebViewClient(new HelloWebViewClient());
   }
  });
       
       
        b3.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    finish();
   }
  });
    }
       
   
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
            webview.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
   
    private class HelloWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }
}

다소 복잡해 보이지만 자동 완성 기능이 있으므로 어렵지 않습니다. 안드로이드는 자바와 XML로 구성되어 있다고 보면 됩니다. 특히 자바의 기초적인 부분을 잘 이해 하고 계시다면 개발은 어렵지 않을 거란 생각이 드네요.



4. 애플리케이션 훝어보기
 

 

Portal 버튼을 눌러 네이버로 이동한 화면입니다. 다시 Home 버튼을 누르면 다음으로 이동합니다. Close 는 화면을 종료하며 finish() 함수를 호출하여 간단하게 애플리케이션을 종료 할 수 있습니다.

안드로이드 JNI 에 대하여...


JNI JAVA에서 Native code를 사용할 수 있는 인터페이스이다. 좀 더 쉽게 말하면 CC++로 작성한 API JAVA에서 호출하게 해준다.

 

이를 위해서 framework의 안드로이드 소스 코드 중 service를 보자. (다른 쪽도 이와 유사하게 구현되어 있다.)

 

/framework/base/service/jni

/framework/base/service/java/com/android/server

 

jni 디렉토리의 Android.mk를 보면 libandroid_servers.so를 만들게 된다. 이는 java/com/android/server/SystemServer.java에서 다음과 같이 호출하게 된다.

 

 

    public static void main(String[] args) {

        if (SamplingProfilerIntegration.isEnabled()) {

            SamplingProfilerIntegration.start();

            timer = new Timer();

            timer.schedule(new TimerTask() {

                @Override

                public void run() {

                    SamplingProfilerIntegration.writeSnapshot("system_server");

                }

            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);

        }

 

        // The system server has to run all of the time, so it needs to be

        // as efficient as possible with its memory usage.

        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

 

        System.loadLibrary("android_servers");

        init1(args);

    }

 

System.loadLibrary에 의해서 libandroid_servers.so가 로드되며 최초로 호출되는 것이 JNI_OnLoad() 이 다. JNI_OnLoad() onload.cpp에서 정의되어 있으며, JNI_OnLoad()가 호출되기 전에 JNI로 정의한 메소드가 호출되어서는 안된다. 이유는 JNI_OnLoad()에서 각각의 서비스가 사용할 수 있는 native code를 등록하기 때문이다. 등록 전에 호출되면 JAVA VM은 관련 함수를 찾을 수 없게 된다. (JNI_OnLoad() System.loadLibrary에 의하여 자동으로 호출되기 때문에 java 파일에서는 호출되는 곳을 찾을 수 없다)

 

 

extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)

{

    JNIEnv* env = NULL;

    jint result = -1;

 

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {

        LOGE("GetEnv failed!");

        return result;

    }

    LOG_ASSERT(env, "Could not retrieve the env!");

 

    register_android_server_KeyInputQueue(env);

    register_android_server_HardwareService(env);

    register_android_server_AlarmManagerService(env);

    register_android_server_BatteryService(env);

    register_android_server_SensorService(env);

    register_android_server_FallbackCheckinService(env);

    register_android_server_SystemServer(env);

 

    return JNI_VERSION_1_4;

}

 

여기에서 호출한 register 함수를 살펴볼 필요가 있다. Register_android_server_HardwareService()를 본다. jniRegisterNativeMethod()에 의해서 method_table com/android/server/HardwareService에 등록한다는 의미이다. 실제로 com/android/server/를 보면 HardwareService.java 파일이 있다. 위의 의미가 HardwareService.java 파일에 등록한다는 의미는 아니다. HardwareService.java 파일에서 정의한 HardwareService 클래스에 등록하여 사용한다는 의미이다. 이렇게 등록되면 HardwareService 클래스에 서는 method_table에 등록된 native 함수를 호출하여 사용할 수 있다. 당연히 다른 클래스에서는 native 함수를 호출할 수 없다.

 

 

static JNINativeMethod method_table[] = {

    { "init_native", "()I", (void*)init_native },

    { "finalize_native", "(I)V", (void*)finalize_native },

    { "setLight_native", "(IIIIIII)V", (void*)setLight_native },

    { "vibratorOn", "(J)V", (void*)vibratorOn },

    { "vibratorOff", "()V", (void*)vibratorOff }

};

 

int register_android_server_HardwareService(JNIEnv *env)

{

    return jniRegisterNativeMethods(env, "com/android/server/HardwareService",

            method_table, NELEM(method_table));

}

 

한 예로 SystemServer.cpp를 보면 SystemServer, ServerThread, DemoThread가 있다. com_android_server_SystemService.cpp 에서 정의된 gMethods[]에 새로운 native 코드 set_mtd_data를 추가하고 이를 ServerThread에서 호출하려고 하면 컴파일에서는 에러가 나지 않지만 실행 시에 에러가 난다. 이 를 해결하기 위해서는 다음과 같이 호출하여야 한다.

 

SystemServer.set_mtd_data(outputsel, (int)0);

 

 

SystemServer 클래스의 메소드 형태로만 호출이 가능하다.

 

만약 동일한 native 코드를 두개 이상의 독립된 클래스에서 사용하려면 당연한 얘기지만 각각에 대하여 따로 등록해야만 한다.

 

다시 com_android_server_HardwareService.cpp 파일의 method_table[]을 보자. 여기에서는 5개의 native 함수가 등록되어 있다. 첫번째 인자가 실제 java에서 호출되면 함수면이고, 두번째 인자는 입출력 인스턴스의 타입을 정의한다. 세번째 인자는 com_android_server_HardwareService.cpp에서 정의한 JNI 인터페 이스 함수이다.

 

HardwareService.java HardwareService 클래스에서 이를 이용하기 위해서는 native 메소드임을 선언하는 과정이 필요하다.

 

public class HardwareService extends IHardwareService.Stub {

    ……

 

private static native int init_native();

    private static native void finalize_native(int ptr);

 

    private static native void setLight_native(int ptr, int light, int color, int mode,

            int onMS, int offMS, int brightnessMode);

 

    private final Context mContext;

    private final PowerManager.WakeLock mWakeLock;

 

    private final IBatteryStats mBatteryStats;

 

    volatile VibrateThread mThread;

 

    private int mNativePointer;

 

native static void vibratorOn(long milliseconds);

    native static void vibratorOff();

}

 

JNI에서 새로운 native 함 수를 추가했다면 java 코드의 클래스에도 반드시 메소드 정의를 추가한다.

안드로이드 애플리케이션 Life Cycle


♦ 안드로이드 애플리케이션 Life Cycle
대부분의 경우에 안드로이드 애플리케이션은 자신 고유의 리눅스 프로세스에 의해 실행된다. 이 프로세스는 애플리케이션이 특정 코드를 수행할 필요가 있을 때 생성되고, 시스템이 다른 애플리케이션에 사용할 메모리를 요청 또는 더 이상 필요없어질 때까지 실행 상태를 유지한다.
안드로이드의 중요한 특성은 애플리케이션의 프로세스 Life Cycle은 애플리케이션 자신에 의해 직접 컨트롤되지 않는다는 것이다. 그것은 시스템이 실행상태를 알고 있는 애플리케이션 부분들의 조합(얼마나 사용자에게 중요한 것인가, 시스템의 여유 메모리가 얼마나 더 남아있는가)으로 결정된다.
애플리케이션 개발자들이 알아야 할 중요한 사항은 어떻게 서로 다른 애플리케이션 컴포넌트(Activity, Service, IntentReceiver)들이 애플리케이션의 프로세스에 영향을 미치는가 하는 것이다. 이러한 컴포넌트들을 정확하게 사용하지 않을 경우, 시스템은 중요한 일을 하고 있는 애플리케이션의 프로세스를 종료시킬 수 있다.
프로세스 lifecycle 버그의 일반적인 예는 onReceiveIntent() 메소드 내에서 Intent를 받고 함수에서 리턴될 때, IntentReceiver가 스레드를 시작하는 것이다. 한번 리턴되고 나면 시스템은 IntentReceiver를 비활성 상태로 인식하게 되고, 그것을 실행하는 호스팅 프로세스는 다른 애플리케이션 컴포넌트가 그 안에서 활성화 되어 있지 않는 한 필요없어지는 것이다. 그러므로 메모리 요청에 의해 언제든지 프로세스가 종료될 수 있고, 생성되어 실행되던 스레드도 종료된다. 이 문제의 해결법은 IntentReceiver로부터 Service를 실행하는 것이다. 그래서 시스템이 그 프로세스를 종료하기전에 여전히 어떤 작업이 활성화 되어 있음을 인식하게 하는 것이다.
유휴 메모리가 부족할 때 어떤 프로세스가 종료되어야 하는지 결정하는 것은 중요한 것이다. 안드로이드는 이것을 “importance hierarchy”를 베이스로 하고, “Importance hierarchy”내에서 실행중인 컴토넌트와 그 컴포넌트들의 상태에 따라 결정한다. 중요도의 순서는 다음과 같다.

 

(1) foreground process : 사용자가 조작중인 최상위 화면의 Activity(onResume() 메소드가 호출된 경우) 또는 현재 실행중인 IntentReceiver(onReceiveIntent() 메소드가 실행중)를 잡고 있는 프로세스이다. 시스템에는 아주 적은 수의 이런 프로세스가 있고, 이러한 프로세스가 실행되기에 극히 부족한 메모리가 있을 경우에만 종료된다. 이러한 동작은 일반적으로 기기가 메모리 페이징 상태에 다다랐을 때이며, 사용자 인터페이스 응답을 유지하기 위해서 취해진다.


(2) visible process : 사용자 화면에는 보여지지만 foreground는 아닌(onPause() 메소드를 호출한 경우) Activity를 잡고 있는 프로세스이다. 예를 들면 foreground activity가 다이알로그를 보여주며 이전 activity는 그 아래에 위치하는 것과 같다. 이런 프로세스는 매우 중요하며, 모든 foreground 프로세스 실행이 종료되기 전까지는 종료되지 않는다.


(3) service process : startService()를 호출한 Service를 잡고 있는 프로세스이다. 이러한 프로세스는 사용자에게 직접적으로 보여지는 것은 아니지만 사용자와 관련된 일반적인 일(mp3를 배경음으로 연주한다던가, 네트워크 데이터를 업로드/다운로드 한다던가 하는등)들을 한다. 그래서 이러한 프로세스는 모든 foreground, visible 프로세스를 유지하기에 메모리가 충분하지 않을때까지 계속 유지된다.


(4) background process : 사용자에게 현재는 보여지지 않는 activity(onStop() 메소드를 호출한 경우)를 잡고 있는 프로세스이다. 이런 프로세스들은 사용자에게 어떠한 영향을 주지 않으며, activity lifecycle을 정확하게 구현하기 위해서 제공된다. 시스템은 메모리가 부족할 경우 언제든지 이런 프로세스 수행을 멈출 수 있다. 가끔식 이러한 프로세스들이 많이 수행되고 있을 때, 메모리 부족시 가장 최근에 사용자에게 보여진 것이 가장 마지막으로 종료되도록 LRU 목록에 유지된다.


(5) empty process : 어떠한 활성화된 애플리케이션 컴포넌트들도 잡고있지 않는 프로세스이다. 이러한 프로세스를 유지하고 있는 이유는 다음에 컴포넌트의 애플리케이션이 시작되어야 할 때 시작 시간을 개선하기 위한 캐시로 사용하기 위해서다. 시스템은 캐쉬된 빈 프로세스와 커널 캐쉬 사이의 시스템 전체 리소스의 균형을 맞추기 위해 이런 프로세스를 종료시킨다.

Activity Manager

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

Alarm Manager

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);


Audio Manager 

AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

Clipboard Manager 

ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);

Connectivity Manager

ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

Input Method Manager

InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);


Keyguard Manager

KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);


Layout Inflater Manager 

LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);


Location Manager 

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


Notification Manager 

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


Power Manager 

PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);


Search Manage

SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);


Sensor Manager 

SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);


Telephony Manager 

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);


Vibrator

Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);


Wallpaper Service 

WallpaperService wallpaperService = (WallpaperService) getSystemService(Context.WALLPAPER_SERVICE);


Wi-Fi Manager 

WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);


Window Manager 

WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

Near Field Communication

 

첨부파일 : 2008년도 NFC폰 시장 전망 및 업체 동향 - 정보통신정책

 

차기 아이폰과 안드로이드에서 지원하기로 한 NFC 기술에 대한 간략한 자료입니다.

 

http://en.wikipedia.org/wiki/Near_Field_Communication

http://wifisland.blog.me/10096977733?Redirect=Log

 

블루투스와 비교설명을 하였으나, 기존 900Mhz 대역 RFID 및 지그비 등의 장점등을 포함하고 있습니다.

현재의 결재, 교통, 주문, 배송, 입출입 등에서 사용되는 근거리 통신기술과 

바코드 기술 등을 모두 커버 할 수 도 있을 것 같습니다.

 

  • Supported data rates : 106,212,424 or 848 kbits/s

Baud

Active device

Passive device

424kBd Manchester, 10% ASK Manchester, 10% ASK
212kBd Manchester, 10% ASK Manchester, 10% ASK
106kBd Modified Miller, 100% ASK Manchester, 10% ASK

  • NFC vs. Bluetooth

NFC Bluetooth V2.1 Bluetooth V4.0
RFID compatible ISO 18000-3 active active
Standardisation body ISO/IEC Bluetooth SIG Bluetooth SIG
Network Standard ISO 13157 etc. IEEE 802.15.1 IEEE 802.15.1
Network Type Point-to-point WPAN WPAN
Cryptography not with RFID available available
Range < 0.2 m ~10 m (class 2) ~1 m (class 3)
Frequency 13.56 MHz 2.4-2.5 GHz 2.4-2.5 GHz
Bit rate 424 kbit/s 2.1 Mbit/s ~200 kbit/s
Set-up time < 0.1 s < 6 s < 1 s
Power consumption < 15mA (read) varies with class < 15 mA (xmit)


 

 

 

출처 : http://techblog.textcube.com/141 

 

NFC는 초단거리 무선통신 기술로 대략 10cm이내의 기기간에 통신을 가능하게 해 준다.

NFC는 ISO/IEC 14443 proximity-card standard (비접촉 카드 또는 RFID) 표준을 확장 한 것으로 스마트카드와 리더기를

하나로 합쳐놓은 것이라고 생각하면 된다.


ISO/IEEE 14443 표준을 확장한 것이기 때문에 NFC 디바이스간 뿐 아니고

기존의 ISO/IEEE 14443 리더기나 스마트카드와도 통신을 할 수 있다.

NFC는 기본적으로 휴대폰에서 사용할 목적으로 만들어졌다.

XD6BLFEoHX.jpg



간단한 기술적인 스펙으로는

- 13.56MHz의 ISM밴드에서 14KHz의 대역폭을 사용
- 최대 동작 거리: 20cm
- 지원하는 통신 속도: 106, 212, 424, 848 Kbit/s
- 동작모드: Passive, Active

NFC 포럼은 현재까지 11개의 스펙을 공개하고 있다.


   * NFC Data Exchange Format (NDEF) - Common data format for devices and tags
   * NFC Tag Types 1,2,3 &4 Operation - Defines RW operation for NFC tags
   * NFC Record Type Definition (RTD) - Standard record types used in messages between devices/tags 
   * Smart Poster RTD - For posters with tags with text, audio or other data
   * Text RTD - For records containing plain text
   * Uniform Resource Identifier (URI) RTD - For records that refer to an Internet resource
   * Generic COntrol Record Type Definition (RTD) - Ways to request an action
   * Connection Handover Specification - How to establish a connection with other wireless technologies

스펙은 http://www.nfc-forum.org/specs 에서 무료 다운받을 수 있다.


현재 NFC는 주로 휴대폰에서 사용되는데 3가지 방식으로 동작하고 있다.

- 카드 에뮬레이션: NFC디바이스(휴대폰)이 기존의 RFID카드와 같이 동작한다.

  즉 리더기에 기존의 카드 대신 휴대폰을 가져다 대면 된다.
- 리더 모드: NFC디바이스가 카드 리더기로 동작하는 모드이다.
- P2P 모드: 두대의 NFC디바이스가 서로 통신하는 모드이다.

이렇게 3가지 모드를 지원하기 때문에 NFC디바이스는 매우 다양한 방법으로 사용할 수 있다.

휴대폰이 교통카드, 문 열쇠등으로 동작(카드 에뮬레이션), 미술관, 박물관 등에서 작품에 휴대폰을 가까이 가져가면

해당 작품의 소개로 연결하기, 스마트카드 결제 단말기(리더모드), 휴대폰간 명함 교환 (P2P 모드)등등이 가능해진다.

그리고 통신거리가 매우 짧기 때문에 보안 문제도 간단해지고 통신을 위한 초기 셋업타임이 매우 짧은것이

 (0.1초 이하) 최대의 장점이다.

현재 휴대폰에는 노키아, 삼성, 모토롤라의 일부 소수 기중에서만 채용되어 있지만 여러곳에서

트라이얼 하는 곳이 많아서 조만간 급속하게 사용이 늘어나리라고 본다.

그리고 이 방식의 통신이 가장 널리 사용되고 있는 곳은 역시 일본이다. 일본은 소니가 개발한 FeLiCa를

교통카드에서부터 신용카드와 멤버쉽카드와 핸드폰, 결제 기능이 있는 손목시계 등, 다양한 곳에서 이 용하고 있다.

XP2Ka2Q48L.jpg


 

XFec5cnw4T.jpg


 

XL9stSU72g.jpg


 

XOacTG2tMp.gif



물론 현재 일본의 FeLiCa기능을 가지고 있는 휴대폰의 경우 카드 에뮬레이션 모드로만 동작한다.

(즉 스마트카드를 휴대폰에 집어넣은 형태) 소니의 발표에 의하면 2억개 이상의 FeLiCa칩을 판매하였다고 하고

가정용 USB리더기도 구매할 수 있다. 또한 일본 내수용 바이오 모델을 가지고 있는 사람들은

터치패드 오른쪽에 아래 사진과 같은 마크가 찍혀 있는것 봤을텐데 그 부분에 FeLiCa리더가 들어있다.

XPqF1LEu1N.jpg


libnfc 에서 오픈소스 NFC 라이브러리(리눅스, Mac OS X, 윈도우)를 구할 수 있고 몇일전에 NFC 칩을 판매하는

프랑스 회사인 Inside ContactlessLinux 2.6 and Windows CE 6.0용 프로토콜 스택인 Open NFC 3.4를

open source Apache License 2.0으로 공개했고 3월 말에는 안드로이드도 지원하는 Open NFC 3.5를 공개할 예정이다.

libnfc에는 여러가지 예제 코드와 함께 사용할 수 있는 하드웨어 목록을 확인할 수 있다.

XDXolTVonC.jpg


 

XNz91QTnsO.jpg



몇가지 종류의 하드웨어가 있는데 현재 가장 쉽고 저렴하게 구할 수 있는 리더로는 ACR-122 NFC가 있다.

몇곳에서 다른 이름으로 팔고 있지만 하드웨어는 기본적으로 동일하고 PN532 NFC Controller를 사용하고 있다.

XfMZC6x4jt.jpg


touchatag 에서도 ACR-122 리더기를 사용(윈도우, 맥용 드라이버 제공)한다.

다른곳에 비해 이 것이 가장 구하기 쉽고 저렴하다.

사진의 리더기와 10장의 스티커로 된 태그를 포함해서 $39.95, 추가로 태그만 구입하는 경우 25장에 $24.95, 500장에 $474.95이다.

touchatag에서도 라이브러리를 제공해 주지만 그걸 사용하지 않고 libnfc를 사용해도 된다.

집의 현관 문 앞에 저 USB리더기를 설치하고 스티커로 되어 있는 태그를 자신의 휴대폰 뒷면에 붙여주면

휴대폰을 집 열쇠로 사용할 수도 있다.

효율적인 모바일앱의 작성은 항상 쉽지 않다. 특 히, 안 드로이드처럼 Dalvik garbage collector 의해 자동으로 메모리가 관리되는 경우 충분히 주의하지 않으면 성능이슈가 발생할 수밖에 없다

성능에 민감한 코드들(layout생성, view시스템의 그리기, 게임의 로직부분)은 필연적으로 비용을 초래한다. 너무 많은 메모리 할당후에는 당신의 앱은 메모리를 해재하도록 잠시 멈출수 있다. 대부분의 경우 사용자가 느끼지 못할정도로 gc는 이루어지는 반면에 리스트를 scroll하거나 게임에서 적을 물리치거나 하는 경우 심각한 성능과 응답성의 저하를 느낄수 있다. 100~200ms정도 gc시간이 걸리는 것은 일반적인 상황은 아니다. 부드러운 애니매이션의 경우 각 프레임이 16~33ms정도의 속도가 필요하다. 초당 10프레임정도로만 떨어져도 사용자는 문제를 느끼게 된다.

대개의 경우 gc는 tons of small, short-lived object, 일부 garbage collector때문에 발생한다. 그리고 그런 object의 collection을 최적화할 수 있으며 그렇게 해서 애플리케이션의 좀더 덜 방해받게 할 수 있다. 안드로이드의 garbage collector는 불행히도 이러한 성능최적화등을 할 수 없다. 

더보기

잦 은 gc를 피해가도록 해주기 위해, 안드로이드 SDK는 allocation tracker라는 툴을 포함시켰다. DDMS의 일부기능으로 되어 있으며 디버깅목적으로 이미 사용하고 있다. 이 툴을 사용하려면 SDK에 포함되어 있는 DDMS를 먼저 실행한다. 이클립스버전의 DDMS에는 아직 지원되지 않는다.

DDMS가 실행되면 해당 애플리케이션 프로세스를 선택하고 Allocation Tracker탭을 클릭하라. 새로운 뷰에서 Start Tracking을 클릭하면 분석하고자 하는 애플리케이션을 선택한다. 준비가 되었다면 Get Allocations를 선택하가. 할당된 object들이 첫번째 테이블에 리스트될것이다. 보여지는 한 line을 선택하면 두번째 테이블에 애플리케이션에 할당된 stack이 보여진다. 어떤 타입의 object들이 할당되었는지는 물론이고 포함된 스래드, 클래스, 파일의 라인까지 표시된다. 아래 스크린샷은 Shelves앱의 listView를 스크롤하는 동안의 할당상태를 보여준다.

성 능에 영향을 주는 부분을 모두 제거할 필요가 없다고 하더라도 코드에서 중요한 이슈를 확인하는데 도움이 될것이다.  예를 들면 내가 보아온 많은 애플리케이션에서 draw시마다 매번 Paint 객체를 새로 생성한다. 이 Paint객체를 하나의 인스탄스로 관리하는 것 만으로 성능이슈를 간단히 개선할 수 있다. 나는 Android source code를 살펴볼것을 강력하게 권고한다. 이유는 성능을 끌어올리기 위해 어떤 기술을 사용하였는지 볼수 있기 때문이다. 그리고 객체의 재사용에 대한 안드로이드가 제공하는 API들을 발견하게 될것이다.

+ Recent posts