FireMonkey Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
FireMonkey 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

FireMonkey 강좌/문서
[5] 안드로이드 API를 파이어몽키에서 사용하기(Toast 메시지 구현)
Humphery [hjfactory] 5709 읽음    2013-12-16 16:12
안드로이드 API를 파이어몽키에서 사용방법을 공유합니다. 제가 이해한 내용 기반으로 작성해서 틀린부분이 있을 수 있으니 혹시 틀린부분이 보이시면 댓글달아 주세요.

안드로이드 API 사용을 위해 파이어몽키로 변환할 대상은 안드로이드 Toast를 기반으로 설명하겠습니다.
Toast는 아래의 그림과 같이 하단에 잠시 나타났다가 사라지는 메시지입니다. 파이어몽키에는 제공하지 않습니다.



* 샘플에서는 아래의 기능을 포함합니다.
  - 기본 위치(하단)에 Toast 메시지 표시
  - 지정된 위치에 Toast메시지 표시
  - 소스코드는 Github에 공개합니다.
    -https://github.com/hjfactory/FMX.Devgear/tree/master/Samples/Android_Toast

설명은 아래의 순서대로 진행하겠습니다.

1, 안드로이드 API 문서확인
2, 파이어몽키에서 안드로이드 API 접근 시 구성
3, 안드로이드 API 컨버팅
4, 사용법 및 샘플코드

| 안드로이드 API 문서확인

변환할 대상인 Toast의 안드로이드 문서는 아래 링크에서 확인 할 수 있습니다.
http://developer.android.com/reference/android/widget/Toast.html
http://developer.android.com/guide/topics/ui/notifiers/toasts.html

위쪽 문서는 API 문서구요, 아래의 문서는 샘플코드 문서입니다.



우선 위의 API문서를 보시면 대략 아래와 같은 단락으로 구성되어있으니 숙지해 주시구요.
* Contants
* Public Constructors
* Public Methods -
* Inherited Methods
* Fields(Toast에서는 미사용)

| 파이어몽키에서 안드로이드 API 접근 시 구성
unit Android.JNI.Toast;
 
interface
 
{$IFDEF ANDROID}
uses
  Androidapi.JNIBridge,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.GraphicsContentViewText;
 
type
  JToast = interface;
 
  JToastClass = interface(JObjectClass)
  ['{F227353E-DCE9-404B-8129-6B1BEFE68151}']
    {Property methods}
    function _GetLENGTH_LONG: Integer; cdecl;
    function _GetLENGTH_SHORT: Integer; cdecl;
    {Methods}
    function init(context: JContext): JToast; cdecl; overload;
    function makeText(context: JContext; text: JCharSequence;
      duration: Integer): JToast; cdecl;
    {Properties}
    property LENGTH_LONG: Integer read _GetLENGTH_LONG;
    property LENGTH_SHORT: Integer read _GetLENGTH_SHORT;
  end;
 
  [JavaSignature('android/widget/Toast')]
  JToast = interface(JObject)
  ['{FC9B3DFD-38CC-4693-9F11-7F3E3647683F}']
    {Methods}
    procedure cancel; cdecl;
    function getDuration: Integer; cdecl;
    function getGravity: Integer; cdecl;
    function getHorizontalMargin: Single; cdecl;
    function getVerticalMargin: Single; cdecl;
    function getView: JView; cdecl;
    function getXOffset: Integer; cdecl;
    function getYOffset: Integer; cdecl;
    procedure setDuration(value: Integer); cdecl;
    procedure setGravity(gravity, xOffset, yOffset: Integer); cdecl;
    procedure setMargin(horizontalMargin, verticalMargin: Single); cdecl;
    procedure setText(s: JCharSequence); cdecl;
    procedure setView(view: JView); cdecl;
    procedure show; cdecl;
  end;
  TJToast = class(TJavaGenericImport) end;
{$ENDIF}
 
implementation
 
end.


파이어몽키에서 Android API 사용하기 위해서는 JavaClass영역(JToastClass)과 JavaInterface영역(JToast)으로 구성 후
실제 파이어몽키에서 사용할 수 있는 Class(TJToast)로 Generic형태로 Import해 사용합니다.
* JToastClass - JavaClass interface
* JToast - JavaInterface interface
* TJToast - Delphi에서 사용할 Class

위와 같이 구성하기 위해서는 아래의 Unit들이 사용(uses)됩니다.
* Androidapi.JNIBridge
* Androidapi.JNI.JavaTypes
* Androidapi.JNI.GraphicsContentViewText

| 안드로이드 API 컨버팅

델파이에서 구현할 부분은 크게 JavaClass와 JavaInterface입니다.
안드로이드 API문서를 보며 어느 부분을 JavaClass와 JavaInterface에 구현할지에 대해 알아보겠습니다.



위 그림의 붉은색 사각형에 포함된 내용이 JavaClass에 포함되고 나머지는 JavaInterface에 포함됩니다.

JavaClass 구현 할 항목
JToast = interface;
 
JToastClass = interface(JObjectClass)
['{F227353E-DCE9-404B-8129-6B1BEFE68151}']
  {Property methods}
  function _GetLENGTH_LONG: Integer; cdecl;
  function _GetLENGTH_SHORT: Integer; cdecl;
  {Methods}
  function init(context: JContext): JToast; cdecl; overload;
  function makeText(context: JContext; text: JCharSequence;
    duration: Integer): JToast; cdecl;
  {Properties}
  property LENGTH_LONG: Integer read _GetLENGTH_LONG;
  property LENGTH_SHORT: Integer read _GetLENGTH_SHORT;
end;


Inherited Methods
  - JToastClass = interface(JObjectClass)와 같이 안드로이드 API에 기술된대로(java.lang.Object) interface를 상속받아 사용합니다.
Constants(상수)
  - 안드로이드 API 상수는 Properties로 구성되며 read 절에 _Get을 추가하여 선언됩니다.
  - 만약, END, BEGIN과 같은 상수는 &END, &BEGIN과 같이 &를 앞에 추가하여 구성됩니다.
  - Property methods에 _Get이 포함된 read 함수가 선언되며 호출규칙은 cdecl으로 지정합니다.
Public Constructors(생성자)
  - 생성자는 init();로 선언되며, 안드로이드의 인자를 그대로 선언해 줍니다.
    (JContext 등의 클래스는 이미 엠바카데로에서 선언(Androidapi.JNI.GraphicsContentViewText)해 놓았으니 매번 구현할 필요없이 잘 찾아서 사용하면 될것 같네요.)
  - 생성자도 cdecl로 호출규칙을 지정하고, Init는 JObjectClass에서 이미 구현되었으므로 overload로 method를 분개합니다.
  - JavaInterface를 반환합니다.(그래서 JToast = interface;를 미리 선언해야 합니다.)
Public Methods(Static)
  - Public Methods에 나열된 메소드 중에서 static으로 선언된 메소드들은 JavaClass에 선언해야 합니다.
  - 저는 static으로 선언된 메소드 중 2번째인 CharSequence text가 2번째 인자로 들어간 메소드만 사용했습니다.
    (모든 메소드를 모두 구현해야 할 필요는 없습니다.)

JavaInterface 구현 할 항목

[JavaSignature('android/widget/Toast')]
JToast = interface(JObject)
['{FC9B3DFD-38CC-4693-9F11-7F3E3647683F}']
  {Methods}
  procedure cancel; cdecl;
  function getDuration: Integer; cdecl;
  function getGravity: Integer; cdecl;
  function getHorizontalMargin: Single; cdecl;
  function getVerticalMargin: Single; cdecl;
  function getView: JView; cdecl;
  function getXOffset: Integer; cdecl;
  function getYOffset: Integer; cdecl;
  procedure setDuration(value: Integer); cdecl;
  procedure setGravity(gravity, xOffset, yOffset: Integer); cdecl;
  procedure setMargin(horizontalMargin, verticalMargin: Single); cdecl;
  procedure setText(s: JCharSequence); cdecl;
  procedure setView(view: JView); cdecl;
  procedure show; cdecl;
end;
 
TJToast = class(TJavaGenericImport) end;


class path
  - 아래와 같이 API문서의 상단에서 class path를 확인하고 JavaSignature를 구성합니다.
   
Inherited Methods
  - JavaInterface도 JObject를 상속받습니다.
Public methods
  - Public methods에서 static으로 선언된 항목을 제외하고 선언합니다.
  - 대부분의 자료형은 이미 Androidapi.JNI.JavaTypes에 선언되었으나 해당 Unit을 참고합니다.

마지막으로 JavaClass(JToastClass)와 JavaInterface(JToast)를 TJavaGernericImport 클래스를 이용해서 실제로 사용할 Delphi class를 선언할 수 있습니다.

| 사용법 및 샘플코드
var
  Toast: JToast;
begin
  CallInUiThread(procedure
  begin
    Toast := TJToast.JavaClass.makeText(SharedActivityContext, StrToJCharSequence(AMsg), TJToast.JavaClass.LENGTH_SHORT);
    Toast.show;
  end);
end;


위의 코드가 Toast 메시지를 화면에 출력하는 샘플코드입니다.
안드로이드 가이드 문서를 참고해서 만들었습니다.

안드로이드 API를 구현한 후에는
TJToast.JavaClass이후에 JavaClass에 선언된 메소드들을 호출하고 반환받은 객체에서 JavaInterface의 메소드를 사용할 수 있습니다.

그리고, CallInUiThread의 경우  UI와 관련된 경우 Thread 처리하지 않으면 화면이 얼어버리는 현상이 발생해서 추가했습니다.
(그냥 구현했더니 얼어버려서, 엠바카데로 소스를 참고했습니다.)

마치며
대부분의 안드로이드 API는 이미 엠바카데로에서 구현해 놓았습니다.
(C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\source\rtl\android 참고: 설치 기본경로 기준)

다만, 안드로이드에 특화된 기능등은 구현되지 않은 것이 있을 것입니다.
그럴경우 위에서 설명한 내용 참고하시면 충분히 포팅하여 사용할 수 있을것 같습니다.
(제 글이 도움이 되었으면 좋겠네요. 만약 어려운 부분이 있으시면 답글 주세요. 함께 고민해 보겠습니다.)

그럼 다음에는 iOS library 사용법이나 NDK 등의 글로 찾아뵙겠습니다.
감사합니다.

원본은 http://blog.hjf.pe.kr/102 에 있습니다.

+ -

관련 글 리스트
5 안드로이드 API를 파이어몽키에서 사용하기(Toast 메시지 구현) Humphery 5709 2013-12-16
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.