Android/App개발2009. 7. 23. 19:33
In order to use in on the device (use the attached busybox.tar)
$ tar -xvf busybox.tar 
$ adb shell 
# mkdir /data/busybox
# exit
$ adb push busybox /data/busybox
$ adb shell 
# cd data/busybox
# ./busybox --install
# export PATH=/data/busybox:$PATH

Posted by 삼스
Android/App개발2009. 7. 20. 20:23
Parcelable Object 만들기 (1) Android Life 

2009/07/17 16:24

복사http://blog.naver.com/visualc98/74522627


[Parcel Class?]

 

Android의 핵심 중에서 Binder Driver라는 녀석이 있습니다.
Linux Kernel의 driver로 되어 있고, IPC이긴 하지만 기존의 IPC와는 살짝 다른 녀석 입니다.

 

저도 어떻게 만들었는지는 잘 모릅니다만, 
shared memory를 통하여 오버헤드도 적고 프로세스 사이에 비동기로 호출도 이루어 진다고 합니다.
그리고 Binder는 기존 IPC처럼 데이터만 전달 하는게 아니라,
하나의 프로세스에서 다른 프로세스로 Object를 넘길 수도 있게끔 설계 되어 있습니다.
(물론 Serialize 기술을 사용하면 Object도 주고 받을 순 있지요.)

 

Binder를 통해서 넘기는 메세지 (data 와 object references) 는 
Parcel 클래스에 저장이 되어서 넘어가게 됩니다. Parcel은 메세지 컨테이너인 셈이죠.

Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport.

Parcel 클래스는 고성능 IPC 전송을 가능하게 끔 설계가 되어 있기 때문에,

모든 객체에 대해서 평범하게 serialization하지 않습니다. 
그래서 모든 Object들을 Binder를 통해 주고 받을 수는 없습니다.

 


[Parcelable Interface]

 

Primitive Type과 Primitive Array Type은 기본적으로 parcelable 합니다.

뭐 그냥 일반 데이터인거죠.
그리고 
Parcelable Interface를 implements한 클래스가 (당연히) parcelable 합니다.

 

오늘 우리가 할 일이 바로 이 Parcelable Interface를 사용하여
parcelable Object를 만드는 일 인 것이죠.

사실 parcelable한 type들이 많이 있습니다만, 나머지는 잘 모르겠군요... 어렵습니다.
여튼 오늘은 parcelable Object를 만드는 것만 생각 합시다.

 


[Parcelable Rect]

 

Rect 클래스야 다들 쉽게 만드실 겁니다.
left, top, right, bottom 4개의 필드만 있으면 되죠.


integer든 float이든 상관 없습니다만....
Android에는 Rect 클래스의 float 버전이 RectF 클래스 라고 따로 되어 있기 때문에,

저는 integer로 만들겁니다.


public class Rect {
    public int left;
    public int top;
    public int right;
    public int bottom;
}


뭐 아주 간단 합니다. 그냥 C에서의 구조체 수준이네요.
이것을 parcelable하게 바꾸어 봅시다.

 

Step 1.


public class Rect implements Parcelable {
    public int left;
    public int top;
    public int right;
    public int bottom;
    
    public int describeContents() {
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(left);
        dest.writeInt(top);
        dest.writeInt(right);
        dest.writeInt(bottom);
    }
}


Parcelable을 implements하게 되면 꼭 추가해야 한다는 메소드 두 개도 같이 넣었습니다.
내용도 채워 봤어요.

 

describeContents() 메소드는 일단 건너뛰고...
writeToParcel() 메소드는 Parcel에 데이터를 쓰는 부분 입니다.
그냥 무작정 쓰면 됩니다. 전 아무 생각 없이 순서대로 그냥 썼습니다.

 

그럼 이제 에러도 없으니 parcelable한 Rect 클래스가 되었느냐... 라고 한다면 아직 아닙니다.
쓰는건 있는데 읽는건 없네요...

 

Parcel로 부터 값을 읽어 오기 위해서는 Parcelable.Creator Interface 가 필요합니다.

 


[Parcelable.Creator Interface]

 

Parcel 에서 Parcelable 클래스의 인스턴스를 만들 때
CREATOR라는 static field를 찾아서 실행 합니다.
CREATOR는 
Parcelable.Creator<T> type 으로 만들어져야 하는데 
이건 선언과 동시에 반드시 initialize 되어야 합니다.

 

클래스 따로 만들어서 initialize 하기도 쉽지 않습니다.
그냥 익명 클래스로 만들어 버립시다.

 

Step 2.


public class Rect implements Parcelable {
    public int left;
    public int top;
    public int right;
    public int bottom;
    
    public int describeContents() {
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(left);
        dest.writeInt(top);
        dest.writeInt(right);
        dest.writeInt(bottom);
    }
    
    public static final Parcelable.Creator<Rect> CREATOR new Creator<Rect>() {
        public Rect createFromParcel(Parcel source) {
            Rect r   = new Rect();
            r.left   = source.readInt();
            r.top    = source.readInt();
            r.right  = source.readInt();
            r.bottom = source.readInt();
            return r;
        }
        public Rect[] newArray(int size) {
            return new Rect[size];
        }
    };
}


Parcelable.Creator<T> 클래스는 createFromParcel() 과 newArray() 메소스가 필요 합니다.

 

newArray() 메소드도 일단 넘어가고...
createFromParcel() 메소드를 보면 리턴이 Rect입니다.
그래서 Parcel에서 값을 읽어 새로운 Rect 인스턴스를 리턴 하는 구조로 만들면 끝입니다.

 

readInt()를 했는데, 이것은 writeToParcel() 메소드에서 썼던 순서대로 읽어 오는 것입니다.
쓸 때는 무작정 썼지만 읽을 때는 조심스럽게 읽어야하죠.

 

이제 비로소 parcelable Rect 클래스를 만들었습니다.
그냥 별거 없군요...

 


[Appendix]

 

위에서 describeContents() 메소드와 newArray() 메소드는 그냥 넘어 갔었습니다.
네... 뭐 사실 잘 모르기도 합니다만, 
그냥 보통 parcelable Object를 만드는데에 크게 중요한 부분은 아니지요. 아하하...

 

describeContents() 에서는 어떤 특별한 객체를 포함하고 있는지에 대한 설명을
리턴값으로 표현 하는 것이라고 보면 됩니다.
bit mask 형식의 integer를 리턴 하며,
값을 체크 할 때 bit mask 체크를 해서 어떤 것들이 들어 있는지 알 수 있습니다.

 

현재 사용하는 플래그는 Parcelable.CONTENTS_FILE_DESCRIPTOR (0x00000001) 
하나 밖에 정의 되어 있지 않습니다.
소스를 다 뒤져 보지 않아서 또 어떤 값들이 쓰이는지는 확인 해보지 못했네요...

 

newArray() 메소드는 그냥 배열로 만들어서 리턴 하는 겁니다.
Parcel.createTypedArray() 메소드에서 newArray() 메소드를 호출 하는 걸 확인 했습니다.
나중에 createTypedArray() 메소드를 사용 할 일이 있다면 newArray()가 호출이 되는 것이지요.

Posted by 삼스
Android/App개발2009. 7. 19. 17:01
Pro. Android 발췌

Posted by 삼스
Android/App개발2009. 7. 12. 00:15
안드로이드 sdk에 제공되는 어플말고 android full source에 들어있는 어플은 이클립스상에서 수정하려고 하면 관련 클래스들이 없어서 빌드가 안되는 문제가 있음.
이 경우 해결하기 위한 방법은 아래 2가지가 있음.

1. android.jar에서 필요로 하는 class들이 없는 경우 full source빌드후 생성된 class파일을 강제로 android.jar파일에 추가한뒤 이클립스에서 빌드하면 됨.

2. http://source.android.com/using-eclipse 에 따르는 방법.
Posted by 삼스
Android/App개발2009. 5. 15. 17:52

playToEnd() function in CodecTest.java .

public static boolean playToEnd(String filePath){
        Log.v(TAG, "shortMediaStop - " + filePath);
        //This test is only for the short media file
        int duration = 200000;
        int updateDuration = 0;
        int currentPosition = 0;
        boolean isPlaying = false;
        MediaPlayer mp = new MediaPlayer();
        try{
            Thread.sleep(5000);
            mp.setDataSource(filePath);
            Log.v(TAG, "start playback");
            mp.prepare();
            //duration = mp.getDuration();
            mp.start();
            Thread.sleep(50000);
        }catch (Exception e){}
        isPlaying = mp.isPlaying();
        currentPosition = mp.getCurrentPosition();
        //updateDuration = mp.getDuration();
        Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
        mp.stop();
        mp.release();  
        //Log.v(TAG, "duration = " + duration);
        //Log.v(TAG, "Update duration = " + updateDuration);
        if (currentPosition > duration || isPlaying)
            return false;
        else
            return true;       
    }

    public static boolean seektoBeforeStart(String filePath){
        Log.v(TAG, "seektoBeforeStart - " + filePath);
        //This test is only for the short media file
        int duration = 0;
        int currentPosition = 0;

        MediaPlayer mp = new MediaPlayer();
        try{
            mp.setDataSource(filePath);
            mp.prepare();
            duration = mp.getDuration();
            mp.seekTo(duration - 10000);
            mp.start();
            currentPosition=mp.getCurrentPosition();
            mp.stop();
            mp.release();
        }catch (Exception e){}
        if (currentPosition < duration/2)
            return false;
        else
            return true;       
    }

Posted by 삼스
Android/App개발2009. 5. 12. 18:30
MediaPlayerDemo_Video.java 참조

           switch (Media) {
                case LOCAL_VIDEO:
                    /*
                     * TODO: Set the path variable to a local media file path.
                     */
                    //path = "sdcard/[PV] YUI - SUMMER SONG.avi"; // failed
                    //path = "sdcard/2008-01-11 02_01_00.3gp"; // ok
                    //path = "sdcard/FighterPilot_H264_720_480_30fps_4.1Mbps_AAC256Q100.mp4"; // fail
                    //path = "sdcard/leekunho_goal6.mp4"; // ok : frame skip
                    //path = "sdcard/Qpang.avi"; // fail
                    path = "sdcard/[M35_700]sample.avi"; // fail
                    if (path == "") {
                        // Tell the user to provide a media file URL.
                        Toast
                                .makeText(
                                        MediaPlayerDemo_Video.this,
                                        "Please edit MediaPlayerDemo_Video Activity, "
                                                + "and set the path variable to your media file path."
                                                + " Your media file must be stored on sdcard.",
                                        Toast.LENGTH_LONG).show();

                    }
                    break;
                case STREAM_VIDEO:

                    /*
                     * TODO: Set path variable to progressive streamable mp4 or
                     * 3gpp format URL. Http protocol should be used.
                     * Mediaplayer can only play "progressive streamable
                     * contents" which basically means: 1. the movie atom has to
                     * precede all the media data atoms. 2. The clip has to be
                     * reasonably interleaved.
                     *
                     */
                    path = "";
                    if (path == "") {
                        // Tell the user to provide a media file URL.
                        Toast
                                .makeText(
                                        MediaPlayerDemo_Video.this,
                                        "Please edit MediaPlayerDemo_Video Activity,"
                                                + " and set the path variable to your media file URL.",
                                        Toast.LENGTH_LONG).show();

                    }

                    break;


            }

            // Create a new media player and set the listeners
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(path);
            mMediaPlayer.setDisplay(holder);
            mMediaPlayer.prepare();
            mMediaPlayer.setOnBufferingUpdateListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

MediaPlayer
  -> setDataSource(path)  : URI로 content의 path가 전달 -> MediaPlayer service로부터 해당 path로 IMediaPlayer생성 -> 생성된 IMediaPlayer내부에 유지
  -> prepare()
      -> prepareAsync_I()
          -> setAudioStreamType() : 생성된 IMediaPlayer의 setAudioStreamType()임
                  in IMediaPlayer.cpp
 status_t setAudioStreamType(int type)
{
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        data.writeInt32(type);
        remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
        return reply.readInt32();
}
          -> prepareAsync() : 생성된 IMediaPlayer의 prepareAsync()임.
                  in IMediaPlayer.cpp
    status_t prepareAsync()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        remote()->transact(PREPARE_ASYNC, data, &reply);
        return reply.readInt32();
    }
     -> wait for prepare done
         if (mPrepareSync) {
            mSignal.wait(mLock);  // wait for prepare done
            mPrepareSync = false;
         }
  -> start()


Posted by 삼스
Android/App개발2009. 5. 12. 10:46
1. ARM GNU/Linux Target Platform 용 Cross-compiler 설치
아래의 사이트에 접속하여 Cross-compiler 를 설치한다.
http://www.codesourcery.com/gnu_toolchains/arm/download.html

2. 간단한 helloandroid.c 를 작성한다.

#include <stdio.h>
 
int main(int argc, char** argv)
{
        printf("Hello Android !n");
        return 0;
}
3. Cross Compile을 통해 ARM GNU/Linux 용 Application을 만든다.
> arm-none-linux-gnueabi-gcc -static helloandroid.c -o helloandroid
(주의: -static option을 필요 사용할 것.)
4. Android Device에 해당 애플리케이션을 Upload 한 후, 실행한다. > adb push helloandroid data/helloandroid
> adb shell
# chmod 755 data/helloandroid
# data/helloandroid
Hello Android ! <- 실행 결과
#
Posted by 삼스
Android/App개발2009. 5. 1. 14:11
sdk1.5에서는 1.1과 달리 AVD라는 것을 지원한다.
1.1버전과 1.5버전을 모두 지원하고 google api도 분리하였다.
따라서 3가지 AVD가 존재하며 eclipse plugin을 사용하려면 AVD를 모두 생성해주어야 한다.


> android list avds
Available Android Virtual Devices:

> android list targets
Available Android targets:
id: 1
     Name: Android 1.1
     Type: Platform
     API level: 2
     Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
id: 2
     Name: Android 1.5
     Type: Platform
     API level: 3
     Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
id: 3
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Description: Android + Google APIs
     Based on Android 1.5 (API level 3)
     Libraries:
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: QVGA-P, HVGA-L, HVGA (default), QVGA-L, HVGA-P

> android create avd --name sdk1.1 --target 1
> android create avd --name sdk1.5 --target 2
> android create avd --name sdk1.5map --target 3

> emulator @sdk1.5

Reference : http://www.taosoftware.co.jp/blog/2009/04/android_sdk15_emulator.html
Posted by 삼스
Android/App개발2009. 4. 25. 11:55
http://www.kandroid.org/board/board.php?board=edupreparation&page=2&command=body&no=4

1. 안드로이드 SDK 설치.

 
먼저 아래의 URL에서 안드로이드 SDK를 다운로드 한 후, 원하는 디렉토리에 설치(압축해제) 합니다.
 
http://code.google.com/android/download.html
 
2008년 11월 현재시점에서 배포되고 있는 안드로이드 SDK는 다음과 같습니다.
 

Platform

Package

Size

MD5 Checksum

Windows android-sdk-windows-1.1_r1.zip 86038515 bytes 8c4b9080b430025370689e03d20842f3
Mac OS X (intel) android-sdk-mac_x86-1.1_r1.zip 79046151 bytes 8c4b9080b430025370689e03d20842f3
Linux (i386) android-sdk-linux_x86-1.1_r1.zip 79345522 bytes 8c4b9080b430025370689e03d20842f3

 
 
2. Java Development Kit (JDK) 설치
 
아래의 URL에서 JDK 5 또는 JDK 6 을 설치합니다.
 
http://java.sun.com/javase/downloads/index.jsp
 
위의 2009년 1월 20일 현재 배포되고 있는 Java SE Development Kit (JDK) 6 Update 11을 설치하시면 됩니다.
(주의사항 : 안드로이드 개발을 위해서는 JRE(Java Runtime Environment) 만 설치해서는 안되니,
                필히 JDK를 설치하시기 바랍니다.)
 
 
3. 이클립스(Eclipse) 설치
 
아래의 URL에서 Eclipse Classic 3.4.1 (151MB) 다운로드 하여 설치합니다.
 
http://www.eclipse.org/downloads/
 
 
4. 안드로이드 이클립스 플러그인  Android Development Tools (ADT) 설치
 
- 이클립스상의 메뉴에서 Help > Software Update 를 선택합니다.
- Software Update Dialog 창의 탭에서 Available Software를 선택합니다.
- Add Site 를 클릭하신 후, https://dl-ssl.google.com/android/eclipse/ 를 입력하고 OK를 클릭합니다.
  (만약, Error 메시지가 발생한다면, http://dl-ssl.google.com/android/eclipse/ 를 입력하고 OK를 클릭)
- 리스트 목록중 https://dl-ssl.google.com/android/eclipse/ 하위의 Developer Tools Check 하신 후,
   Developer Tool 하위의 Android Development Tools와 Android Editor Check 도 확인하신 후,
   Install 을 클릭합니다. (인스톨 과정에서 약관에 동의하신 후, Finish를 클릭합니다)
- 이클립스가 다시 실행되고 나면, 메뉴의 Window > Preferences를 선택합니다.
- Preferences Dialog 창의 왼쪽 탭에서 Android를 선택한 후,
   SDK Location에 위에서 설치(압축해제)한 안드로이드 SDK의 위치를 지정한 후 Apply를 Click합니다.
 
5. 간단한 안드로이드 예제 애플리케이션 작성 및 실행
 
- 이클립스상의 메뉴에서 File > New > Android Project 를 선택합니다.
- New Android Project Dialog 창에서 아래와 같이 항목을 기입합니다.
      Project name : HelloAndroid
      Package name : org.kandroid.sample
      Activity name : HelloAndroid
      Application name : HelloAndroid
- Ctrl-F11 key를 누른 후, Run-As Dialog 창이 뜨면 Android Application을 선택한 후, OK를 클릭합니다.
  (  또는 위에서 생성된 프로젝트, 즉 HelloAndroid에서 마우스 우측버튼을 누른 후,
      Run-As에서 Android Application을 선택하여도 됩니다.
      또한, Run-As에서 Run Configurations를 선택한 후, 다양한 실행관련 설정을 하셔도 됩니다.)
- 이제 안드로이드 에뮬레이터상에서 HelloAndroid라는 애플리케이션의 실행을 확인하실 수 있을 겁니다.
 
6. Eclipse에 SVN 플러그인 설치
 
인터넷에 존재하는 많은 안드로이드 애플리케이션 소스들이 svn 상에 존재하는 경우가 많습니다.
이를 효과적으로 활용하기 위해선, svn 플러그인을 설치하는 것이 바람직합니다.
 
- 이클립스상의 메뉴에서 Help > Software Update 를 선택합니다.
- Software Update Dialog 창의 탭에서 Available Software를 선택합니다.
- Add Site 를 클릭하신 후, http://subclipse.tigris.org/update_1.0.x 를 입력한 후 OK를 클릭합니다.
- 리스트 목록중 http://subclipse.tigris.org/update_1.0.x 하위의 Subclipse Plugin을 Check 하신 후,
   Subclipse Plugin 하위의 목록중 상위버전 하나만을 Check 하신 후,
   Install 을 클릭합니다. (인스톨 과정에서 약관에 동의하신 후, Finish를 클릭합니다)
- 이클립스가 다시 실행됩니다.
- 이클립스상의 메뉴에서 Window > Open Perspective > Others를 클릭합니다.
- Open Perspective Dialog 창에서 SVN Repository Exploring 을 선택합니다.
- SVN Repository 와 SVN Annotate Tab 하단이 아이콘 중 SVN+(Add SVN Repository)을 클릭하신 후,
   새로운 SVN Repository URL을 등록하셔서 사용할 수 있습니다.
Posted by 삼스
Android/App개발2009. 4. 23. 11:21
http://www.kandroid.org/board/board.php?board=androidsource&command=body&no=17

안드로이드 소스코드내의 아래의 위치에 존재하는 문서를 참고하시면 안드로이드 Native 라이브러리 및 
해당 라이브러리를 static, 또는 dynamic하게 linking하는 Native 애플리케이션을 제작하는 법에 대한 설명이
존재합니다. 
 
~/mydroid/development/pdk/ndk/README
 
위의 문서를 참조하여, 아래와 같은 절차를 거치시면 다양한 native lib. 및 application을 제작 테스트 해 볼 수
있습니다.

 
1. 가장 먼저 해야할 일은 다음과 아래의 URL에 있는 문서에서의 다음의 두 절차, 
    즉 6번까지의 작업과 8번의 goldfish 부분에 대한 build를 마무리 해야 함.
 
   http://www.kandroid.org/board/board.php?board=androidsource&command=body&no=4
 
  
중략...
 
   6. 안드로이드 빌드 하기
       $ make 
 
   8. Kernel 별도로 빌드하기
        - goldfish
 
        $ cd ~/mydroid/kernel
        $ make goldfish_defconfig ARCH=arm
        $ make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- 


 
2. ~mydroid/development/pdk/ndk/config/config.mk 를 다음과 같이 수정한다.
 
<android_full_src_path> 는 각자의 host pc에 설치된 android full source의 root directory 를 지정하면 됩니다.
 
CC         := ~/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc
AR         := ~/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-ar
INC        := -I<android_full_src_path>/bionic/libc/arch-arm/include 
-I<android_full_src_path>/bionic/libc/include 
-I<android_full_src_path>/kernel/include 
-I<android_full_src_path>/bionic/libm/include 
-I<android_full_src_path>/bionic/libm/include/arm 
-I<android_full_src_path>/bionic/libstdc++/include
LINK       := -nostdlib -Bdynamic 
     -Wl,-T,<android_full_src_path>/build/core/armelf.x 
     -Wl,-dynamic-linker,/system/bin/linker 
     -Wl,-z,nocopyreloc 
     -L<android_full_src_path>/out/target/product/generic/obj/lib 
     -Wl,-rpath-link=<android_full_src_path>/out/target/product/generic/obj/lib 
     <android_full_src_path>/out/target/product/generic/obj/lib/crtbegin_dynamic.o
POSTLINK := <android_full_src_path>/out/target/product/generic/obj/lib/crtend_android.o
%.o: %.cpp
        $(CC) $(CFLAGS) -fno-exceptions -fno-rtti $(INC) -o $@ -c $<
%.o: %.c
        $(CC) $(CFLAGS) $(INC) -o $@ -c $<

 
 
3. ~mydroid/development/pdk/ndk/sample/Makefile.lib 를 다음과 같이 수정한다.
 

NDK_BASE   := ..
include $(NDK_BASE)/config/config.mk
SOURCES    := hellolibrary.c
OBJECTS    := $(SOURCES:.c=.o)
LIBS       := -lc -lm
ALIB       := <android_full_src_path>/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a
all: sharedlib staticlib
# Using shared and static suffixes as these are going in the same directory;
# typically you would not do this as you would make only one version,
# but if we don't we'll screw up the linking because of linker defaults.
staticlib: $(OBJECTS)
        $(AR) -cr libhello-static.a $(OBJECTS)
sharedlib: hellolibrary-shared.o
        $(CC) -nostdlib -Wl,-soname,libhello-shared.so -Wl,-shared,-Bsymbolic -L<android_full_src_path>/out/target/product/generic/obj/lib $^ $(LIBS) -o libhello-shared.so -Wl,--no-undefined $(ALIB)
hellolibrary-shared.o: hellolibrary.c
        $(CC) -c -fpic $(INC) -o $@ $^
clean:
        rm -rf *.o libhello-static.a libhello-shared.so

 
4. native library 및 application 제작 및 테스트
 
먼저 ~/mydroid/development/pdk/ndk/로 cd 하신후 부터 아래의 절차를 수행하면 됩니다.
하지만, 아래의 과정을 수행하는 과정에서 shared library를 테스트 하기 위해서는
아래의 예제에 있는 libhello-shared.so 가 반드시 /system/lib 아래에 설치되어야 합니다.
하지만, 현재의 emulator는 /system partition이 ro 모드로 되어 있기 때문에 설치가 불가능합니다.
/system partition을 rw 모드로 바꾸는 작업이 필요한데..번거로울까봐 이곳에서는 가장 간단한 방법
(아래의 0번)
제시하도록 하겠습니다.
 
0번) emulator의 /system partition을 ro -> rw 로 바꾸는 방법. (필수)
 
    - 아래의 새로운 ramdisk.img 를 다운로드 한다.
       
 ramdisk.img(136.2KB)
   
    - 에뮬레이터에 존재하는 ramdisk.img를 backup한다.
      예) android-sdk-windows-1.0_r2 oolslibimages  아래 존재하는 
           ramdisk.img 를 ramdisk.img.orig 로 rename 한다.
    
    - 위에서 다운받은 새로운 ramdisk.img 를 위의 위치로 복사한다.
 
    - emulator를 실행한다.
        
 
1) 간단한 hello world 샘플 애플리케이션 제작
 
  cd ../sample
  make clean
  make
 
  adb push hello system/app
  adb shell
  # cd system/app
  # chmod 755 hello
  # ./hello
  Hello from the NDK; no user libraries.
  # exit
 
2) c++ binary hello_cpp.cpp 애플리케이션 제작 
 
  make -f Makefile.hello_cpp clean
  make -f Makefile.hello_cpp hello_cpp
 
  adb push hello_cpp system/app
  adb shell
  # cd system/app
  # chmod 755 hello_cpp
  # ./hello_cpp
  C++ example printing message: Hello world!
  # exit
 
4) shared library 제작 및 해당 library를 제작하는 사용하는 애플리케이션 제작
 
  make -f Makefile.lib clean
  make -f Makefile.lib sharedlib
  make -f Makefile.uselib clean
  make -f Makefile.uselib use_hellolibrary-so
 
  adb push libhello-shared.so system/lib
  adb push use_hellolibrary-so /system/app
  adb shell
  # cd system/app
  # chmod 755 use_hellolibrary-so
  # ./use_hellolibrary-so
  Library printing message: Hello from the NDK.
  # exit
 
5) static library 제작 및 해당 library를 static으로 링크한 애플리케이션 제작
 
  make -f Makefile.lib clean
  make -f Makefile.lib staticlib
  make -f Makefile.uselib clean
  make -f Makefile.uselib use_hellolibrary-a
 
  adb push use_hellolibrary-a system/app
  adb shell
  # cd system/app
  # chmod 755 use_hellolibrary-a
  # ./use_hellolibrary-a
  Library printing message: Hello from the NDK.
  # exit
Posted by 삼스