오늘은 그래서 자바 외부 클래스가 어떻게 동작해서 리눅스에서 돌아가는 지에 대한 메커니즘을 제 나름대로 설명하기로 하겠습니다
사실 이것을 설명하기 위해서 Hello World를 찍어 본다는 것은 개발자로서 심심하고 짜증나는 일이 될 수 있으니 다른 것을 가지고 해보면 좋겠는 데요
우선 xml과 dynamic class loading이라는 기술을 가지고 구현해 보는 것도 좋을 것 같아서 이 두가지 기술을 가지고 플러그 인을 함 만들어 보는 것으로 하겠습니다
사실 저도 플러그 인이라는 것을 확실히 뭐다라고 정의하긴 그렇지만, 이렇게 정의하도록 하겠습니다(사실 저도 잘 모릅니다ㅡ.ㅡ;;)
“플러그 인이란 주 프로그램 즉 여기선 컨테이너 프로그램의 스팩에 맞도록 정의가 되어서 올라 갈 수 있는 조각 프로그램 혹은 모듈” 이라고 정의하고 싶습니다. 원래는 애플릿 같은 것이나 이클립스 플러그 인 같은 것들을 생각 할 수 있는 데요
애플릿은 웹브라우져(이제는 인터넷 익스플로러겠죠 -- 슬프네 ...) 없이 돌아 가는 것은 힘들고,
이클립스 플러그 인은 말 그대로 이클립스가 없으면 돌아 가기 힘든 애플리케이션이겠죠
사실 플러그 인은 잘 정의되어 있는 인터페이스( 그것이 무엇이든 간에)로 상호간의 규약이 존재하고 그 규약에 위배되지 않는 한 플러그 인으로서 자격이 있다라는 것인데 여기서 말하는 플러그 인을 만든다는 것은 기간적으로나 능력으로나 한계가 있는 부분이라서
그냥 다음과 같이 내 맘대로 아무렇게나 구성 하도록 하겠습니다...(^^;;)
그럼 어떤 플러그인을 만드는 것인가는 다음과 같이 GUI를 구성해서
플러그인 버튼을 누르게 되면 우리가 저번에 만든 온도 변환 프로그램을 실행 시키도록 하겠습니다.
대신 실행 시키는 것은 코드 상에서 온도 변환 프로그램을 컴파일 타임에서 올리는 것이 아니라 런타임 상에서 필요 시
즉, plugin 버튼이 클릭 되는 액션이 일어 났을 때 플러그인 클래스를 따로 정의할 플러그 인을 받아 들인 xml 규약에서 읽어 들여 시스템 상에서 로딩 하는 것으로 하겠습니다
그럼 저번에 만든( 물론 제가 만든 건 아니지만) 온도 변환 프로그램은 UI에 대한 레이아웃이 이미 main.xml에 정의가 되어 있었습니다.
그래서 사용자가 굳이 UI 관련 애플리케이션을 만들지 않아도 되었지만 이번 예제 프로젝트 같은 경우에는 런타임 상에서 정의 되는 것이고 기존의 안드로이드 메커니즘에 의한 로딩이 아니기 때문에 xml에 정의 되었던 코드를 일일이 뜯어서 자바로 구현 하도록 하겠습니다
저번 예제의 코드는 main.xml을 작성하고 코드에서 단지 다음과 같이 불렀더랬죠….(^^)
setContentView(R.layout.main);
그리고 각가의 UI에 대한 레퍼런스는 text = (EditText) findViewById(R.id.EditText01); 와 같은 방식으로 참조 하도록 하는 예제 였습니다
우선 이것을 자바로 만들기 위해서 main.xml에서 레이아웃을 잠시 살펴보면
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/myColor">
<EditText
android:id="@+id/EditText01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:inputType="numberSigned|numberDecimal">
</EditText>
<RadioGroup
android:id="@+id/RadioGroup01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/RadioButton01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/celsius"
android:checked="true">
</RadioButton>
<RadioButton
android:id="@+id/RadioButton02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fahrenheit">
</RadioButton>
</RadioGroup>
<Button
android:id="@+id/Button01"
android:layout_height="wrap_content"
android:onClick="@string/buttonHandler"
android:layout_width="wrap_content"
android:text="@string/calc"></Button>
</LinearLayout>
위에서 보시다 시피 온도 변환 프로그램은 EditText, RadioGroup, RadioButton, 그리고 그냥 버튼 하나로 구성된 UI 로 구성되어 있습니다 그리고 각 속성 값이나 이름은 strings.xml에 정의된 것을 불러서 씁니다
위의 내용이 플러그 인이 되어야 함으로 자바로 바꾸고 이 플러그 인을 담을 수 있는 UI가 하나 있어야 될 필요성이 있을 것 같습니다 그래서 컨테이너 클래스를 하나 만들기로 결심을 하고 컨테이너의 UI는 가장 간단하게 버튼 하나로 가져가는 것으로 하겠습니다
자, 그럼 만약 위의 프로그램이 만들어 지면 기본 로직을 제외한 이벤트 부분을 다시 만드는 것이라 제가 다시 패키지를 정해도 위의 온도 변환 프로그램 만드신 분이 욕하지는 않을 것이라 믿고
컨테이너 패키지 이름을 com.aa.lec.container 라 정하고, 플러그인 클래스를 com.aa.lec.plugin으로 정하겠습니다
기본 적인 이벤트 로직은
첫째, 테이너 패키지는 안드로이드에서 사용자 애플리케이션이 불려 질 때 실행 한다
둘째, 플러그 인 패키지는 plugin 버튼에 액션이 들어왔을 때 즉 눌려 졌을 때, xml에서 클래스 이름 및 속성 등을 읽어서 런타임 상에서 클래스를 로딩하여 실행 하는 것으로 정하겠습니다
뭐 너무 간단해서 로직이라고 붙이기에는 뭐하지만 그래도 위와 같은 로직을 정해놓고 시작하는 걸로 하겠습니다
그럼 천리길도 한걸음 부터라는 말이 있듯이
우선 이렇게 라이브러리를 분리하기 이전에 우선 전체 돌아가는 애플리케이션을 하나 만들고 구동이 되는 지 확인한 이후에 각각의 모듈을 분리하고 라이브러리로 만든 다음 실행하는 순서로 진행 하겠습니다
우선 컨테이너 클래스를 MyContainer.java로 만들고 아래와 같이 작성 하겠습니다.
package com.aa.lec.container; /*패키지를 다시 정의 합니다*/
import com.aa.lec.plugin.*; /*플러그인 패키지를 정의 합니다*/
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.view.WindowManager;
import android.widget.TableRow.LayoutParams;
import android.graphics.Color;
public class MyContainer extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void plugInClickHandler(View view) {
switch (view.getId()) {
case R.id.PlugInBtn:
// get a reference for the TableLayout
android.widget.TableLayout table = (android.widget.TableLayout) findViewById(R.id.TableLayout01);
// create a new TableRow
android.widget.TableRow row = new android.widget.TableRow(this);
row.addView(new ConvertTemp(this));
table.addView(row,new android.widget.TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
break;
}
}
}
위에서 말했듯이 간단하게 가져가기 위해서 테이블 레이아웃을 정해 놓고 버튼을 클릭할 때 마다 ConvertTemp를 호출하는 것으로 하겠습니다(한 번 이상 누르면 안되겠지요^^;;)
그리고 main.xml 파일을 자바로 옮겨놓기 위한 클래스를 ConvertTemp라고 정하겠습니다
단순히 처음 예제에서 보았듯이 EditText, RadioGroup, RadioButton, 그리고 그냥 버튼 하나로 구성된 UI를 구현 할 것입니다. 대신 좀 다른 것은 배경색이라든지 아니면 이름 라벨등이 없는 버전 입니다
가급적이면 이 모든 속성은 xml 파일에서 읽어 들여서 세팅 하는 버전을 만들기 위한 초기 버전이라고 생각 하시면 될 듯 합니다
package com.aa.lec.plugin; ; /*패키지를 다시 정의 합니다*/
import android.widget.*;
import android.content.Context;
import android.view.View;
import android.graphics.Canvas;
import android.widget.LinearLayout;
import android.view.ViewGroup.LayoutParams;
public class ConvertTemp extends FrameLayout
{
Context cntxt;
EditText txtTemp; ; /*텍스트 필드*/
RadioGroup radiogrp; /*라디오 버튼 그룹*/
RadioButton radio01; /*라디오 버튼 1*/
RadioButton radio02; /*라디오 버튼 2*/
LinearLayout linearLayout; /*기본 레이아웃*/
static android.view.ViewGroup.LayoutParams lpFillWrap=new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
public ConvertTemp(Context cntxt)
{
super(cntxt);
this.cntxt = cntxt;
linearLayout=new LinearLayout(cntxt);
linearLayout.setOrientation(LinearLayout.VERTICAL);
setUpUI();
}
void setUpUI()
{
txtTemp = new EditText(cntxt);
radiogrp = new RadioGroup(cntxt);
radio01 = new RadioButton(cntxt);
radio02 = new RadioButton(cntxt);
radiogrp.addView(radio01);
radiogrp.addView(radio02);
linearLayout.addView(txtTemp, lpFillWrap);
linearLayout.addView(radiogrp, lpFillWrap);
this.addView(linearLayout,lpFillWrap);
return;
}
}
각 안드로이드 자바의 세세한 내용은 적지 않겠습니다 왜냐 하면 현재 문서의 제목 처럼 내멋대로 안드로이드를 탐험하기 위해서 필요한 것이기 때문에 만드는 것 뿐이니까요.... 위의 세세한 내용은 구글 선생님께 여쭈어 보면 저보다는 더 확실히 알려 줄것이라는 믿음도 있구요...^^
그래서, 기본 적인 이 플러그인의 레이아웃은 LinearLayout 입니다 그리고 main.xml 파일의 내용을 자바로 옮겨 놓았다고 생각 하시면 될 거 같구요. 나머지 궁금한 점은 API를 참고 하면 될 듯 합니다
우선 이 프로그램이 잘 돌아 가는 지 확인을 해 봅시다
에뮬레이터를 띄우고 ant install 명령으로 컴파일하고 설치 과정을 거칩니다
컴파일 및 설치 성공 메시지가 아래와 같이 나왔습니다
그러면 애플리케이션을 에뮬레이터에서 구동 해 보면
비교를 위해서 저 번 예제인 “Temperature Converter”와 “Temperature Converter Container”가 보입니다
이번에 만든 프로그램인 “Temperature Converter Container”을 구동 하면
테이블레이아웃 상의 첫번째 로우의 버튼만 있는 모습이구요
버튼을 클릭하면 클릭이벤트를 받아서 온도 변환 프로그램을 다음 로우에 표시 하도록 하였습니다
위 와 같이 버튼을 눌렀을 때의 모습이 나옵니다 예전 버전의 애플리케이션과(아래그림) 비교 해 봤을 때 위에서 언급 했듯이 라벨 및 배경색이 나오지 않는 모습입니다
물론 의도된 바지요(우하하^^)
별 어려운 부분은 없었으리라 생각 됩니다 그리고 첨부한 소스 파일 확인 하시면 되실거 같구요
이제 플러그 인 클래스를 나누어 보고 xml 파일로 이 애플리케이션을 느슨한 결합으로 이루어지도록 하는 문제만 남았는데,
이 부분은 다음 시간에 천천히 다루어 보도록 하겠습니다.
'모바일프로그래밍 > 안드로이드' 카테고리의 다른 글
내 멋대로 안드로이드 - 7 (0) | 2022.07.21 |
---|---|
내 멋대로 안드로이드 - 6 (0) | 2022.07.20 |
내 멋대로 안드로이드 - 4 (0) | 2022.07.18 |
내 멋대로 안드로이드 - 3 (0) | 2022.07.17 |
내 멋대로 안드로이드 - 2 (0) | 2022.07.16 |