하이브리드 앱 강좌 #2. 안드로이드 앱 개발의 기초

개요

이 글에서는 본격적인 하이브리드 앱 개발에 앞서 안드로이드 앱 개발에 필요한 기초 개념을 설명합니다.
프로젝트 생성, 앱 실행, 레이아웃, 이벤트 처리를 간략한 예제를 통해 다룹니다.

새 프로젝트 생성

이클립스를 처음으로 실행한 화면에서 자식창인 Android IDE 옆의 X 버튼을 클릭해서 닫고 나면 다음 화면을 볼 수 있습니다.

첫 화면

새 프로젝트1

툴바 첫번째에 있는 New 아이콘 옆의 아래 화살표(▼)를 클릭하고 Android Application Project를 클릭합니다.

새 프로젝트2

New Android Application 창에서 다음 항목을 지정해야 합니다.

  • Application Name: 구글 플레이스토어, 앱 목록 등에 나타나는 앱 이름을 지정합니다.
  • Project Name: 개발 중에 이클립스에 저장될 프로젝트명을 지정합니다.
  • Package Name: 개개의 어플을 구분하는 고유한 아이디에 해당합니다. 패키지명이 동일한 어플이 여러 개가 있더라도 한 폰에는 하나만 설치할 수 있습니다. 따라서 각 어플은 전 세계에서 중복되지 않는 패키지 이름을 가져야 하고, 관례적으로는 개발자의 웹사이트의 도메인 네임을 뒤집어서 많이 사용합니다.
  • Minimum Required SDK: 이 앱이 호환되는 안드로이드 운영체제 버전의 최솟값을 지정합니다. 현재 기준으로는 Android 2.3.3에 해당하는 API 10 버전을 권장합니다.
  • Target SDK: 이 앱이 사용할 모든 기능을 제공하는 안드로이드 운영체제 버전의 최솟값을 지정합니다. Minimum Required SDK에 비해 너무 높은 값을 지정할 경우 하위 버전 호환을 위한 코드 작성이 길어집니다. 개발의 편의성을 위해서는 Minimum Required SDK와 동일하게 설정하는 것을 권장합니다.
  • Compile With: 기본값대로 최신 컴파일러를 사용하면 됩니다.
  • Theme: 배경색, 글자색, 버튼색 등 어플의 전반적인 색상을 Dark, Light 등에서 선택할 수 있습니다. 안드로이드 설정 화면을 예를 들면 갤럭시 시리즈는 배경색이 검정인 Dark Theme, 옵티머스 시리즈는 배경색이 흰색인 Light Theme를 사용하고 있습니다.

Minimum Required SDK에 API 10을 권장하는 이유를 알기 위해서는 아래 링크를 통해 현재 전세계에서 사용중인 안드로이드 기기의 운영체제 버전에 대한 통계를 확인해야 합니다.

Dashboards | Android Developers

버전 통계

2013년 8월 1일 기준으로 전세계에서 안드로이드 2.3.3 진저브레드 (API 10) 이상의 버전을 사용중인 사람이 96.1%이므로 이를 기준으로 삼는 것이 좋습니다.
안드로이드 2.2 프로요 (API 8) 버전을 기준으로 삼을 경우 추가로 2.6%의 사람들에게 어플을 제공할 수 있지만 진저브레드 버전에서만 제공하는 기능들을 사용하기 까다로워집니다.

새 프로젝트3

다음 단계에서는 앱의 아이콘을 직접 만들지, 액티비티를 자동으로 생성할지, Workspace 폴더 내에 새 프로젝트를 생성할지 여부를 묻습니다.
기본값대로 두고 Next 버튼을 클릭합니다.

새 프로젝트4

앞에서 앱의 아이콘을 직접 만들겠다고 선택했기 때문에 나타나는 화면입니다.
직접 이미지를 선택하거나, 클립아트 중에서 고르거나, 원하는 문자열을 통해서 아이콘을 생성할 수 있습니다.

새 프로젝트5

액티비티를 자동으로 생성하겠다고 선택했기 때문에 나타나는 화면입니다.
Create Activity를 체크된 상태로 두고, 목록 중에서 Blank Activity를 선택합니다.

새 프로젝트6

생성할 액티비티에 관한 정보를 입력합니다.

  • Activity Name: 생성할 Java 클래스의 이름입니다. ?????Activity 와 같은 형태로 지정합니다.
  • Layout Name: 생성할 xml 파일의 이름입니다. layout_?????와 같은 형태로 지정합니다.
  • Navigation Type: 레이아웃 형태를 지정합니다. 일단은 None을 선택합니다.

새 프로젝트 생성됨

여기까지 마친 뒤에는 위와 같은 화면을 볼 수 있습니다.

안드로이드 프로젝트 구조

프로젝트 구조

  • src: .java 파일이 저장됩니다.
  • assets: 앱에 들어갈 .htm, .css, .png, .jpg, .mp4 등의 파일들을 종류 제한, 파일명 제한 없이 자유롭게 넣을 수 있습니다. 하위 폴더를 생성할 수 있습니다. 앱의 패키지 파일(.apk)의 압축을 풀면 그대로 노출됩니다. AssetManager를 통해 접근합니다.
  • res: 앱에 들어갈 이미지, 레이아웃, 메뉴, 문자열 등을 넣을 수 있습니다. 해당되는 폴더에 안에만 파일을 추가할 수 있고, 임의로 하위 폴더를 생성할 수 없습니다. 앱의 패키지 파일의 압축을 풀어도 노출되지 않습니다. R이라는 클래스를 통해 접근합니다.
  • AndroidManifest.xml: 앱에 관한 정보를 기록하는 파일로서, 어플명, SDK 버전, 액티비티 목록, 앱이 사용하는 권한(Permission) 등을 기록합니다. 이 파일에 기록되지 않은 액티비티를 실행하거나, 여기에 기록되지 않은 권한을 사용하려고 하면 앱의 실행이 중단됩니다.

앱 실행

실행1

앱을 처음으로 실행하기 위해서는 툴바에서 Run Project 버튼 옆의 아래 화살표(▼)를 클릭하고 Run Configurations를 클릭합니다.

실행2

좌측 화면에서 Android Application을 선택하고 New launch configuration 아이콘을 클릭합니다.

실행3

Project를 지정하기 위해 Browse 버튼을 클릭합니다.

실행4

Project Selection 창에서 실행하려는 프로젝트를 선택하고 OK 버튼을 클릭합니다.

실행5

Name 칸에 적당한 이름을 적습니다.
대개는 프로젝트명을 복사, 붙여넣기 하는 것을 권장합니다.
다음으로는 Apply 버튼을 클릭하고 Run 버튼을 눌러서 실행합니다.

실행6

앱을 처음 실행할 때에만 앞의 과정이 필요합니다.
다음부터 앱을 실행할 때에는 Run Project 버튼 옆의 아래 화살표(▼)를 클릭하고 해당 프로젝트를 선택하면 됩니다.

실행7

PC와 케이블로 연결되어 있던 스마트폰에서 해당 앱이 실행됩니다.

실행8

앱을 종료해 보면 설치된 앱 목록에 방금 실행한 앱이 있는 것을 확인할 수 있습니다.

레이아웃

레이아웃01

새 프로젝트를 생성했을 때에 기본적으로 적용된 레이아웃은 Relative Layout입니다.
이번 예제에서는 이것을 Linear Layout으로 바꾸어 줍니다.
이클립스의 오른쪽 위에 있는 Outline 창에서 RelativeLayout을 선택하고 마우스 오른쪽 버튼을 클릭합니다.
컨텍스트 메뉴에서 Change Layout을 클릭합니다.

레이아웃02

Change Layout창에서 New Layout Type으로 LinearLayout(Vertical)을 선택하고 OK 버튼을 클릭합니다.

레이아웃03

다음으로는 Palette에서 버튼을 선택해서 레이아웃 창으로 드래그합니다.

레이아웃04

TextView 아래에 Button이 배치된 것을 볼 수 있습니다.
버튼의 width를 조절하기 위해서 버튼이 선택된 상태에서 오른쪽 아래의 Properties 창의 Width를 선택합니다.
Width 필드가 보이지 않을 경우 Layout Parameters 필드 왼쪽에 있는 [+]버튼을 클릭하면 됩니다.

레이아웃05

기본값으로 지정되어 있던 wrap_content 대신에 match_parent를 선택합니다.

레이아웃06

버튼의 width가 늘어나 화면을 가득 채우는 것을 볼 수 있습니다.
다음으로는 버튼의 텍스트를 수정하기 위해 오른쪽 위의 Outline 창에서 버튼을 선택하고 마우스 오른쪽 버튼을 클릭합니다.
컨텍스트 메뉴에서 Edit Text를 클릭합니다.

레이아웃07

Resource Chooser 창에서 New String 버튼을 눌러 새로운 String을 생성합니다.

레이아웃08

Create New Android String 창에서 String 칸에 원하는 문자열을 입력합니다.
New R.string. 칸에는 이 문자열을 할당할 java 변수명을 입력합니다.
이렇게 하면 .java 파일에서 R.string.(변수명)으로 해당 String 값을 사용할 수 있게 됩니다.
입력이 완료되면 OK 버튼을 클릭합니다.

레이아웃09

다시 Resource Chooser 창에서 조금 전에 생성한 Android String을 확인할 수 있습니다.
OK 버튼을 클릭합니다.

레이아웃10

버튼의 텍스트가 바뀐 것을 확인할 수 있습니다.

레이아웃11

이번에는 TextView의 weight를 조절해서 버튼의 높이는 최소가 되고, TextView의 높이는 최대가 되도록 조절하겠습니다.
화면에서 TextView를 클릭하여 선택합니다.
오른쪽 아래의 Properties 창에서 Weight 필드를 선택하고 숫자 1을 입력하고 엔터키를 눌러 입력합니다.

레이아웃12

TextView의 높이가 늘어나 최대값이 되고 Button은 최소한의 높이만을 가진 채로 화면 아래에 배치되는 것을 확인할 수 있습니다.

이벤트 처리 #1: id 지정

이벤트를 처리하기 위해서는 id가 필요합니다.
앞에서 생성한 Button과 TextView에 각각 id를 지정하겠습니다.

이벤트01

Outline 창에서 버튼을 선택하고 마우스 오른쪽 버튼을 클릭한 뒤 컨텍스트 메뉴에서 Edit ID를 선택합니다.

이벤트02

Rename Resource 창에서 New Name에 원하는 id를 입력합니다.
이 예제에서는 buttonTest로 지정합니다.

이벤트03

마찬가지로 텍스트뷰를 선택하고 마우스 오른쪽 버튼을 클릭한 뒤 컨텍스트 메뉴에서 Assign ID를 선택합니다.

이벤트04

텍스트뷰의 id를 textViewTest로 지정합니다.
버튼과 텍스트뷰의 id 지정이 끝난 뒤에 Outline을 보면 다음과 같습니다.

이벤트05

이벤트 처리 #2: 멤버변수 선언

이벤트06

화면 왼쪽 위의 Package Explorer 창에서 MainActivity.java를 더블클릭하면 아래와 같은 코드를 볼 수 있습니다.

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

MainActivity 클래스 안에 멤버변수로 textViewTest, buttonTest를 선언합니다.
또한 ButtonTest의 클릭 이벤트를 처리할 OnClickListener를 선언합니다.

public class MainActivity extends Activity {

	TextView textViewTest;
	Button buttonTest;
	OnClickListener cListener;

	@Override
	protected void onCreate(Bundle savedInstanceState) { ... }

	@Override
	public boolean onCreateOptionsMenu(Menu menu) { ... }

}

이 때에 보다 쉽게 입력하기 위해서는 이클립스의 자동완성 기능을 사용하는 것이 편리합니다.
예를 들어 OnClickListener를 전부 입력할 필요 없이 onclickl까지 입력한 상태에서 Ctrl+Space bar를 입력하면 자동완성이 가능한 단어들의 목록을 볼 수 있습니다.

이벤트07

여기에서는 android.view.View에 포함된 OnClickListener를 선택하면 됩니다.

한편 TextView와 Button에 빨간색 밑줄이 그어진 것은 해당 클래스가 import 되어 있지 않기 때문입니다.
이를 해결하기 위해서는 TextView에 마우스 포인터를 가져다 두고 잠시 기다리면 됩니다.

이벤트08

이러한 팝업창에서 import ‘TextView’ (android.widget)을 선택하면 됩니다.

이벤트 처리 #3. 멤버변수 연결

앞에서 선언한 TextView, Button 변수를 실제 텍스트뷰, 버튼과 연결해야 합니다.
onCreate 메서드에서 findViewById() 메서드를 사용하면 됩니다.
주의할 점은 반드시 setContentView() 메서드가 실행된 이후에 findViewById() 메서드를 실행해야 한다는 점입니다.

public class MainActivity extends Activity {

	...

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		textViewTest = (TextView)findViewById(R.id.textViewTest);
		buttonTest = (Button)findViewById(R.id.buttonTest);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) { ... }

}

이벤트 처리 #4. 이벤트 리스너

이벤트 리스너는 어디에서 생성해도 상관 없으나 이번 예제에서는 다른 멤버변수와 마찬가지로 onCreate 메서드 안에서 생성하겠습니다.
OnClickListener는 onClick() 메서드를 구현해야 합니다.
cListener = new OnClickListener까지만 입력한 후에 이클립스의 자동완성 기능(Ctrl+Space bar)을 사용하면 필요한 코드를 작성해 줍니다.
onClick 메서드 안에서는 파라미터인 v를 통해서 어떤 버튼이 클릭된 것인지를 확인하고 그에 맞게 코드를 실행합니다.
마지막으로는 cListener를 button에 OnClickLister로 지정해 줍니다.

public class MainActivity extends Activity {
	
	TextView textViewTest;
	Button buttonTest;
	OnClickListener cListener;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		...
		
		cListener = new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				switch (v.getId()) {
				case R.id.buttonTest:
					textViewTest.setText("buttonTest가 클릭됨");
					break;
				default:
					break;
				}				
			}
		};

		buttonTest.setOnClickListener(cListener);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) { ... }

}

앱을 실행해 보면 다음과 같은 화면을 볼 수 있습니다.

이벤트09

버튼을 클릭하면 텍스트뷰에 새로운 문자열이 표시되는 것을 볼 수 있습니다.

이벤트10

이번 강좌에서는 안드로이드 앱 개발의 기초를 다루었습니다.
다음 강좌에서부터 본격적인 하이브리드 앱 개발을 다루겠습니다.

관련 포스트

하이브리드 앱 강좌 #1. 개발환경 준비, 설치

안드로이드 하이브리드 앱을 개발하기 위해 다음과 같은 것들을 준비해야 합니다.

기본적으로 필요한 것

기본적인 HTML 코딩 능력
기본적인 Java 코딩 능력
안드로이드 스마트폰
스마트폰-PC 연결 케이블

개발환경 준비 #0: 필요한 파일들

개발환경 준비 #1 ~ #3이 마치고 난 뒤에는 다음과 같은 파일들이 준비되어 있어야 합니다.
(32bit 윈도우, 삼성 안드로이드 스마트폰을 가지고 있는 경우)

다운로드 완료

그러면 각각의 파일을 준비하는 방법을 알아봅니다.

개발환경 준비 #1: ADT Bundle

예전에는 이클립스를 다운받고 ADT 플러그인을 추가하고 안드로이드 SDK Tool을 설치하고 이클립스에서 설정을 바꾸어 주는 등의 번거로운 과정이 필요했습니다.
이런 과정은 복잡한데다 시간도 오래 걸려서 안드로이드 개발을 처음 시작하는 사람들에게 일종의 장벽 역할을 했습니다.
그러나 이제는 이러한 과정 없이 ADT Bundle을 다운받아서 원하는 폴더에 압축을 풀기만 하면 됩니다.

다운받기 위해서는 아래의 링크를 클릭해서 Android Developers 홈페이지에 접속합니다.

Android Developers

ADT Bundle 다운로드

첫 화면 아래의 Get the SDK 링크를 클릭합니다.

ADT Bundle 다운로드

오른쪽의 Download the SDK 버튼을 클릭합니다.

ADT Bundle 다운로드

약관 내용에 동의한다는 체크를 클릭하고 자신의 운영체제에 따라 32비트 또는 64비트를 선택한 후에 Download the SDK ADT Bundle for Windows 버튼을 클릭합니다.
적절한 경로를 선택하고 다운로드를 시작합니다.

개발환경 준비 #2: JDK

안드로이드로 개발을 하기 위해서는 JDK가 필요합니다.
글을 작성하는 현재의 최신 Java SE Development Kit 버전은 7u25입니다.
아래 링크를 클릭하여 오라클 홈페이지의 JDK 다운로드 페이지에 접속합니다.

Java SE Downloads

JDK 다운로드

화면 중간의 Java DOWNLOAD 링크를 클릭합니다.

JDK 다운로드

다음 화면에서 Accept License Agreement를 체크한 뒤 32비트 윈도우를 사용중이라면 jdk-7u25-windows-i586.exe를, 64비트 윈도우를 사용중이라면 jdk-7u25-windows-x64.exe를 다운받습니다.

개발환경 준비 #3: USB 드라이버

개발된 어플을 안드로이드 스마트폰에서 테스트하기 위해서는 스마트폰 USB 드라이버가 설치되어 있어야 합니다.

삼성 스마트폰의 경우 통합 USB 드라이버를 아래 링크에서 제공합니다.

휴대폰/MP3 Player 지원센터

USB 드라이버 다운로드

위쪽의 통합 USB 드라이버 탭을 선택합니다.

USB 드라이버 다운로드

통합 USB 드라이버 버튼을 클릭하여 다운받습니다.

LG 스마트폰의 경우 USB Driver for Android를 아래 링크에서 제공합니다.

LG Mobile : 다운로드 센터

USB 드라이버 다운로드

목록에서 자신의 스마트폰을 선택합니다.

USB 드라이버 다운로드

그 다음 화면에서 USB Driver for Android 버튼을 클릭해서 다운받습니다.

설치 #1: ADT Bundle

별다른 설치 과정이 필요 없습니다.
다운받은 ADT Bundle 압축파일을 원하는 폴더에 압축을 풀면 설치가 끝납니다.

ADT Bundle 설치

설치 #2: JDK

다운받은 JDK 설치 파일을 실행하여 설치합니다.

JDK 설치

설치 #3: USB 드라이버

핸드폰을 PC와 연결하지 않은 상태에서 다운받은 USB 드라이버 설치 파일을 실행하여 설치합니다.
드라이버 설치가 끝난 뒤 핸드폰을 PC와 연결합니다.
설치 과정이 다시 한 번 자동으로 진행되고 난 뒤에 PC가 핸드폰을 인식합니다.

Eclipse 실행

모든 설치 과정이 끝난 뒤에는 실제 개발을 시작하기 위해 Eclipse를 실행해야 합니다.
앞서 설치 #1에서 설명한 대로 ADT Bundle의 압축을 풀고 나면 다음과 같은 폴더/파일를 확인할 수 있습니다.

ADT Bundle 설치 후

eclipse 폴더 내의 eclipse.exe 파일을 실행합니다.

Eclipse를 처음 실행할 경우 Workspace 경로를 지정하라고 하는 창이 뜹니다.

Workspace 선택

Workspace 폴더에는 앞으로 생성할 안드로이드 앱 프로젝트들이 저장됩니다.
따라서 이미 사용하고 있던 Workspace 폴더를 찾아서 지정하거나, 새로운 폴더를 생성하여 Workspace 폴더로 지정하면 됩니다.
Use this as the default and do not ask again을 체크하면 앞으로는 이 단계 없이 곧바로 Eclipse가 실행됩니다.

Eclipse를 처음 실행할 경우 Android SDK 사용 통계를 구글에 전송할 것인지를 묻습니다.

통계 전송

개인정보는 전송되지 않으며, Android SDK가 개선되는 데에 참여하기를 원하면 Yes를 선택하면 됩니다.
Finish 버튼을 클릭하여 닫고 난 뒤에 다음과 같은 Eclipse 화면을 볼 수 있습니다.

이클립스

그 이후의 과정은 이어지는 다음 글을 통해서 다룹니다.

관련 포스트

하이브리드 앱 강좌 #0. 서론

안드로이드 앱을 만들려던 어떤 웹개발자의 이야기

PHP를 주로 사용하고 HTML, javascript를 이용하여 웹사이트를 개발해 본 적이 있는 개발자가 있습니다.
스마트폰이 널리 보급되고 모바일 환경이 확대되면서 모바일 앱을 개발할 필요성을 느낍니다.
인터넷으로 “안드로이드 개발 강좌” 등을 검색해보지만 설치 과정부터 복잡함을 느낍니다.
우여곡절 끝에 안드로이드 개발환경 준비를 마치고 첫 어플리케이션을 만들어보지만 실행조차 쉽지 않습니다.
흰 바탕에 검은 글씨로 Hello, World만 덩그러니 출력된 첫 어플리케이션에서 디자인과 기능을 발전시켜 보려 하지만 곳곳에서 에러가 발생합니다.
빌드가 된 이후에 실행해도 “어플리케이션이 응답하지 않습니다”라는 메시지가 나오면 해결방법을 몰라 당황스럽기만 합니다.
에러 수정을 포기하고 어플리케이션을 새로 만드는 과정을 반복하다 보면 짜증이 납니다.
이대로 앱 개발을 포기하기는 싫어 학원이나 책을 알아보다가 지쳐 모바일 앱 개발은 당분간 미루기로 합니다.
어느날 “하이브리드 앱”이라는 개념을 알게 되고 인터넷에서 강좌를 검색해 봅니다.
그러나 제대로 된 자료가 부족하고 심지어 하이브리드 앱의 개념 설명조차 제대로 되어 있지 않습니다.
강좌 대신 학원, 카페 홍보로 끝나는 블로그글만 잔뜩 나옵니다.
그러다가 어디에선가 하이브리드앱의 성능이 떨어진다는 내용을 보고 난 뒤에는 마지막 남은 의욕마저 상실합니다.

하이브리드 앱의 개념

모바일 앱은 개발 방식에 따라 네이티브 앱, 웹 앱, 하이브리드 앱으로 나누어 볼 수 있습니다.

네이티브 앱은 게임과 메신저 앱 등을 비롯한 대부분의 앱에 해당됩니다.
통화, 푸쉬 알림, GPS, 카메라, 진동, 녹음, 저장공간 활용 등 모바일 기기에서 지원하는 기능을 전부 사용할 수 있습니다.
실행 속도도 빠르고 앱스토어, 플레이스토어 등에 업로드해서 배포할 수 있습니다.
인터넷이 사용 가능하지 않은 환경에서도 일부 기능을 작동할 수 있습니다.
개발 기간이 오래 걸리고 개발 비용도 많이 필요합니다.

Instagram
인스타그램: 네이티브 앱

웹 앱은 일반적인 모바일 웹사이트를 의미합니다.
각종 포털 사이트, 커뮤니티 사이트, SNS 사이트 등을 예로 들 수 있습니다.
통화, 푸쉬 알림 등의 기능을 직접 사용할 수 없습니다.
실행 속도는 빠르지만 인터넷 접속 속도에 영향을 받습니다.
앱스토어, 플레이스토어 등에 업로드해서 배포할 수 없고 즐겨찾기(책갈피) 기능으로 홈 화면에 추가해서 접속할 수는 있습니다.
인터넷이 사용 가능하지 않은 환경에서는 사용할 수 없습니다.
네이티브 앱에 비하여 짧은 기간에 개발할 수 있고 개발 비용도 상대적으로 저렴합니다.

네이버
네이버 모바일 홈페이지: 웹 앱

하이브리드 앱은 이러한 네이티브 앱과 웹앱의 중간에 위치합니다.
웹 앱을 웹뷰를 통해 네이티브 앱 속에 포장한 것이라고 보면 됩니다.
대개는 웹브라우저 어플처럼 웹뷰(Webview)가 화면의 대부분을 차지하고 있는 형태입니다.
개발자는 특정한 웹페이지만 보여주는 웹브라우저와, 거기에서 보여줄 웹페이지를 개발하면 됩니다.
네이티브 앱의 카메라, 통화 등 네이티브 앱에서 사용할 수 있는 기능을 사용할 수 있습니다.
실행 속도는 기본적으로 네이티브 앱, 웹앱에 비해서 느리지 않지만, 게임 등에 필요한 고성능의 그래픽을 제공하기는 비효율적입니다.
인터넷이 사용 가능하지 않은환경에서도 일부 기능을 작동할 수 있습니다.
개발 기간과 비용은 네이티브 앱과 웹 앱의 중간 정도입니다.

Financial Times
Financial Times: 하이브리드 앱

위의 내용을 도표로 정리하면 아래와 같습니다.

native-hybrid-web
출처: http://www.scribd.com/doc/50805466/Native-Web-or-Hybrid-Mobile-App-Development

다양한 플랫폼 지원(X축)과 모바일 기기의 기능 활용(Y축) 정도에 따라 도식화하면 아래와 같습니다.

native-v-hybrid
출처: http://www.icenium.com/blog/icenium-team-blog/2012/06/14/what-is-a-hybrid-mobile-app-

하이브리드 앱으로 개발하는 것이 유리한 경우

모든 경우에 하이브리드 앱으로 개발하는 것이 적절한 것은 아닙니다.
다음과 같은 어플은 하이브리드 앱으로 개발하는 것이 좋습니다.

  • Android, iOS, Blackberry, WindowsPhone 등의 여러 모바일 플랫폼에서 작동하는 어플
  • GPS, 카메라, 통화 등의 모바일 기기 기능을 사용하는 어플
  • 인터넷 접속이 안 되는 상황에서도 작동하는 어플
  • 네이티브 앱에서만 얻을 수 있는 고성능의 그래픽이 필요하지 않은 어플

하이브리드 앱 개발 시 주의할 점

하이브리드 앱 개발은 기본 이상의 안드로이드 앱 개발 능력과 기본 이상의 웹페이지 개발 능력이 필요합니다.
즉 Java, CSS, HTML, javascript 등을 어느 정도는 할 줄 알아야 합니다.

하이브리드앱은 단순한 웹브라우저가 아닙니다.
단지 특정 웹사이트를 보여주기 위해서라면 굳이 앱을 개발할 필요가 없고, 개발하더라도 앱스토어의 검수를 통과할 수 없습니다.
웹사이트의 접근성을 높이기 위한 목적이라면 다음과 같이 즐겨찾기를 홈화면에 추가하도록 안내하면 됩니다.

홈에 바로가기 추가

홈에 추가된 바로가기

하이브리드앱을 쉽게 개발하기 위해서는 jQueryMobile이나 SenchaTouch 등의 자바스크립트 프레임웍을 사용하여 웹페이지를 개발하고 이를 PhoneGap, Appcelerator, Appspresso 등으로 포장하는 방법을 택하게 됩니다.
그러나 이러한 방식으로 개발할 경우 성능의 저하가 나타나고, 특히 스크롤을 할 때에 두드러집니다.
따라서 본 강좌에서는 이러한 프레임웍을 사용하지 않고 하이브리드앱을 만드는 방법을 다룹니다.

하이브리드 앱 개발 강좌

강좌는 다음과 같은 순서대로 진행하겠습니다.

#1. 개발환경 준비, 설치

#2. 안드로이드 앱 개발의 기초

#3. 웹브라우저형 앱

#4. 전자책형 앱

#5. 하이브리드형 앱

…(계속)…

참고 자료

관련 포스트

혈소판 헌혈을 했다

오프를 맞아 헌혈을 했다.
이번이 26번째 헌혈.

사실 자유롭게 헌혈을 하기 위해 학생 때부터 인턴 8월을 기다려 왔다.
이유는 간단했다. 말라리아 위험지역 여행력.

학생 때에 해외로 의료봉사활동을 갔고, 의료봉사지역은 대개 말라리아 위험 지역이었기 때문에 여행 후 1년간은 전혈, 혈소판 헌혈이 불가능하고 혈장 헌혈만 가능했다.
문제는 봉사활동을 여름(7월)마다 매년 다녀왔기 때문에 전혈, 혈소판 헌혈이 불가능한 기간이 1년씩 매 번 연장된다는 점이었다.
따라서 내가 전혈이나 혈소판 성분 헌혈이 가능하게 되는 것은 인턴이 되어 해외로 봉사활동을 다녀올 수 없게 된 이후였다.

그리고 작년 라오스로 봉사대를 다녀온 지 1년이 지나 드디어 8월이 되었다.
마침 퇴근 후 헌혈을 할 여유가 생겨 일산동구청 근처에 있는 헌혈의 집을 찾았다.
꼼꼼한 문진 이후에 전혈 헌혈이 가능하다는 판정을 받았다.
처음에는 나에게 전혈 헌혈을 할 것인지를 물었으나, 내가 혈소판 헌혈을 하고 싶다고 얘기했다.
문진하던 간호사는 반가워하면서 내게 한 시간 반 정도의 시간 여유가 나는지 묻고 피검사를 했다.
오른팔에서 헌혈하겠다고 하니 내 왼팔에서 vacutainer에 채혈하여 EDTA bottle에 담는 것을 보며 “CBC를 위해서 저렇게 많이 뽑을 필요 없이 0.5cc만 뽑으면 될텐데” 하는 생각을 잠시 했다가 직업병이라는 생각이 들었다.
지혈하는 동안 금세 CBC 결과가 나왔고 혈소판 수치가 29k라서 헌혈하기에 충분하다는 얘기를 들었다.

준비가 다 된 뒤에 누워 오른팔에서 헌혈을 시작했다.
책도 읽고 웹 서핑도 하다 보니 한 시간 정도의 시간이 지나갔고 어느새 헌혈은 끝나 있었다.
헌혈이 끝나갈 때쯤에는 입술도 저리고 몸에 힘도 빠져서 약간 힘들기도 했다.

헌혈을 마치고 돌아오는 길은 길게 느껴지기는 했지만 약간의 보람이 있었기에 걸을만 했다.
매번 헌혈할 때마다 느끼는 보람이라는 것은 단순한 헌혈증이나 기념품에서 유래한 것이 아니다.
내가 만났던 혈액종양환자 중 한 명에게 내가 제공한 혈액이 제공될 수도 있다는 생각.
젊고 건강하다는 특권을 감사하게 여기고 이것을 보다 가치있게 쓰겠다는 생각.
지금이 아니면 할 수 없는 일은 지금 해야 한다는 생각.

할 수 있을 때까지 헌혈은 계속할 생각이다.

관련 포스트

암센터 자궁외과 인턴 후기

국립암센터 자궁외과

국립암센터에서는 다른 병원에서의 일반적인 과 구분을 따르지 않고 장기별로 센터를 구분지어 진료를 한다.
즉 일반외과, 흉부외과, 산부인과 등으로 나누는 것이 아니라 위암외과, 폐암외과, 자궁외과 등으로 부른다.
국립암센터의 자궁외과는 다른 병원에서의 부인과에 해당하며, 자궁 이외에도 난소, 나팔관, 질 등을 포함하는 부인과 종양을 다룬다.
자궁경부암, 자궁내막암, 자궁근종, 난소암, 외음부암 등을 수술로 치료한다.
수술적 치료가 불가능한 상태라고 다른 병원에서 들었거나, 혹은 더 큰 병원에 가서 수술받으라고 이야기 들은 환자들이 대개 국립암센터 자궁외과를 찾는다.
물론 이곳에서는 LLETZ(Large Loop Excision of the Transformation Zone), myomectomy와 같은 간단한 수술도 많이 하지만, explorative laparotomy 이후의 cytoreductive surgery, total/anterior pelvic exenteration와 같은 큰 수술을 많이 한다.

자궁외과 수술장 인턴

길게만 느껴졌던 한 달이 지나갔다.
나는 자궁외과 수술장 인턴이었고, 나의 7월은 곧 국립암센터 병원동 4층 수술장 11번방과 14번방이었다.

자궁외과에서는 아침에 시작해서 저녁에 끝나는 긴 수술들을 하루에도 여러 개씩 하는 일이 흔하다.
특히 수술장 인턴은 쉴 틈 없이 수술에 들어가며, 하루 종일 서서 수술을 보조하기 때문에 몸이 편하지 않았다.
지난 한 달 동안 정규시간(오후 5시) 이내에 수술이 끝난 적이 한 손에 꼽을 정도로 적다.

낮에는 몸이 피곤했고, 저녁에는 집에 잘 못 갔지만, 평생 해보지 못할 다양한 수술을 경험해 보았다는 것에 만족한다.
TAH+BSO(total abdominal hysterectomy+bilateral salpingo-oophorectomy) 수술에 내가 first assist로 참여했던 것은 그다지 신기한 편이 아니었다.
복강경 수술에 first assist로 참여한 수술들이 인상적이었고, 특히 RH+PALND(radical hysterectomy+paraaortic lymph node dissection)에서 scope을 잡았던 것이 기억에 남았다.
또한 배를 열자마자 아무리 석션해도 끝이 없는 점액질이 몇 리터씩 쏟아져 나오던 pseudomyxoma peritonei(복막의 가성점액종) 환자에 대한 고식적인 수술(palliative surgery; 일시적으로 병의 증상을 완화하기 위한 목적으로 하는 수술)도 기억에 남는다.
이런 수술들은 내가 산부인과를 전공하지 않는 이상 평생 다시 해보지 못할 의미 있는 경험이었다.
수술을 보조한다고 하여 질병 자체에 대해 배우고 해당 수술의 차례를 외운 것은 아니다.
수술이란 어떤 것인지에 대해 본질적으로 고민하며 배울 수 있었고, 집도의를 보조하여 수술을 원활하게 진행하기 위한 눈치와 감각을 익힐 수 있었다.
몸은 힘들었지만 유익했던 한 달이었다.

관련 포스트

안드로이드 4.3 젤리빈 업데이트 후기

안드로이드 4.3 젤리빈

지난 2013년 7월 24일(현지 시각)에 새로운 안드로이드 버전이 발표되었습니다.

버전 번호는 4.3이고, 이름은 이전과 마찬가지로 젤리빈(Jelly Bean)이라는 이름을 유지했습니다.

발표 직후부터 OTA(Over the air) 업데이트가 제공되기 시작했습니다.

업데이트 과정

저는 국내 KT버전 갤럭시 넥서스(SHW-M420K)에 SKT 유심을 장착하고 언락한 뒤 해외 순정판 안드로이드 4.2.2 yakju 버전을 설치하여 사용하고 있었습니다.

안드로이드 4.3 발표 이후 OTA 업데이트를 받기 위해 매번 시스템 업데이트 확인을 했지만 “시스템이 최신 상태입니다.”라는 메시지만 확인할 수 있었습니다.

시스템이 최신 상태입니다

안드로이드 OTA 업데이트는 모두에게 동시에 제공되는 것이 아니라, 정해진 차례가 되어야 업데이트가 가능하다고 알려주는 방식이기 때문입니다.

인터넷을 찾아보니 정해진 차례를 무시하고 일찍 업데이트를 하는 2가지 방법이 알려져 있습니다.

하나는 업데이트 이미지를 PC에 다운받고, PC와 연결하여 이미지를 덮어씌우는 방법입니다.

저는 이전에도 이런 방식으로 4.2.2 yakju 버전을 설치해서 사용하고 있었지만 번거로운 방법이고, 자칫 잘못하면 핸드폰이 초기화되거나 벽돌이 될 수 있는 위험성이 있습니다.

다른 한 가지 방법은 구글 서비스 프레임웍의 데이터를 지우고 OTA 업데이트를 받는 것입니다.

설정 – 애플리케이션 – 전체 – Google Services Framework – 데이터 지우기를 차례로 선택하면 됩니다.

Google Services Framework

앱 데이터를 삭제하시겠습니까

그런 뒤 설정 – 휴대전화 정보 – 시스템 업데이트 – 지금 확인을 선택해 보면 OTA 업데이트를 할 수 있습니다.

배터리가 부족하거나 와이파이 연결이 되어 있지 않은 경우에는 OTA 업데이트를 할 수 없습니다.

와이파이에 연결된 상태에서 OTA 업데이트를 시행하면 139.3 MB 크기의 업데이트 파일을 다운받은 후 재부팅합니다.

Android 4.3 System Update

재시작 및 설치

설치 취소

몇 분 간의 업데이트와 재부팅 이후 확인한 운영체제 버전은 다음과 같습니다.

휴대전화 정보

업데이트 후 좋은 점

카메라 어플의 인터페이스가 약간 달라졌습니다.

카메라 어플

카메라 어플의 기능에는 큰 차이가 없습니다.

구글 킵 어플이 기본적으로 제공됩니다.

구글 킵 아이콘

메모, 사진 메모, 음성 메모, 체크리스트 등을 쉽게 만들고 관리할 수 있습니다.

특히 음성 메모를 남기면 이를 자동으로 텍스트로 변환하여 녹음 파일과 함께 저장해 줍니다.

구글 킵

메모 내용은 구글 계정과 자동으로 동기화되고, 위젯도 제공하기 때문에 편리하게 사용할 수 있습니다.

구글 킵 위젯

개별 어플의 권한을 켜거나 끌 수 있습니다.

다만, 운영체제상에서 직접 지원하지는 않고 서드파티 어플을 사용해야 합니다.

대표적인 것이 Permission Manager 입니다.

안드로이드 어플이 사용하는 대표적인 권한인 위치, 개인(주소록, 캘린더), 메시지, 기기(진동, 알림) 등을 사용하는 어플의 목록을 보여주고, 어플을 선택하여 특정 권한을 사용하지 못하도록 할 수 있습니다.

Permission Manager

4.3 이전 버전의 안드로이드에는 지원되지 않아 설치할 수 없습니다.

그 대신에 사용할 수 있는 어플로는 Permission Master 등이 있습니다.

업데이트 후 아쉬운 점

대부분의 어플에는 문제가 없었습니다.

그러나 몇몇 어플은 호환이 되지 않았습니다.

대표적인 것이 MX 플레이어, Dice 플레이어 등 동영상 재생 어플입니다.

아예 설치가 되지 않거나, 설치 이후에 실행하더라도 지원하지 않는 안드로이드 버전이라고 나오고 종료되거나, 실행한 뒤에 아무 메시지 없이 다운되기도 합니다.

MX 플레이어

그러나 이러한 현상은 새로운 운영체제 버전이 나온 이후에 흔히 발생하는 일이고, 시간이 지나면 곧 해결되리라 기대합니다.

한편, 구글 플레이 스토어에서 어플을 다운받거나 업데이트 하려고 하면 RPC:S-5:AEC-0 에러가 발생했습니다.

RPC AEC

원인을 알아보니 강제로 OTA 업데이트를 하기 위해 Google Services Framework의 데이터를 지웠기 때문에 구글 계정 정보에 문제가 생긴 것이었습니다.

설정에서 구글 계정을 삭제하고 다시 등록하니 문제가 해결되었습니다.

관련 포스트

첫 집도를 했다

어제 있었던 일이다.

나는 이번 달에 암센터 자궁외과 수술장 인턴으로 근무중이다.
매일 아침 8시에 수술장으로 출근했다가 오후 4시~9시에 수술장에서 나오는 일정을 반복하고 있다.

그렇게 매일 반복되는 하루 중에서도, 어제는 나에게 특별한 날이 되었다.
암을 제거하는 큰 수술을 하던 중간에 점심시간이 되었다.
때마침 충수절제술을 할 단계였다.
그 수술 내의 다른 과정과는 달리, 충수절제술을 할 때에는 손이 많이 필요하지 않기 때문에, 같이 수술하던 참여하던 사람 중 2명은 점심식사를 하러 보내고, 나와 집도의 선생님만 남아서 충수절제술을 하기로 했다.

그런데 갑자기 집도의 선생님께서 나에게 앞으로 어떤 과에 관심이 있는지 물어보셨다.
내가 수술하는 과에 관심이 있다고 말씀드리자, 선생님께서 나에게 충수절제술을 집도할 기회를 주셨다.
물론 메스만 내가 들었을 뿐, 집도의 선생님이 시키시는 대로 마치 아바타처럼 수술하는 것이었다.

이전에 다른 선생님들께서 충수절제술을 하시는 과정을 몇 번 보았기 때문에 내가 수술 방법을 알고 있다고 생각했지만, 막상 내가 직접 해보려니 쉽지는 않았다.
그러나 집도의 선생님께서 한 단계씩 차분히 알려주신 덕분에 무사히 충수절제술을 해낼 수 있었다.

그 수술의 나머지 과정이 어떻게 진행되었는지는 기억나지 않는다.
그러나 메스로 충수를 잘라낼 때의 날카로우면서도 묵직했던 손맛은 기억에 남는다.
본과 1학년 해부학 실습 때에 스칼펠로 카데바를 절개하던 것과 비슷하면서도 느낌이 사뭇 달랐다.

그날 오후에 있었던 또 다른 수술에서는 피부를 봉합하는 과정에서 내가 직접 매듭을 만들기도 했다.
집도와 마찬가지로 실제 수술에서 매듭을 만드는 경험도 난생 처음으로 해 보았다.
여러 모로 2013년 7월 9일 화요일은 나에게 의미 있게 기억될 것이다.

참고로 이렇게 해당 수술의 첫 집도를 한 것을 ‘이와이’라고 부른다.
이를 기념하기 위해 당시에 수술방에 있던 사람들에게 대접하는 것이 관례이다.
나는 커피를 대접할 예정이다.

관련 포스트

삶, 죽음, 그리고 CPR

삶과 죽음

삶과 죽음의 사이에는 질병이 있다.
질병과 죽음의 사이에는 무엇이 있는가?에 대한 답 중 하나를 인턴 의사의 입장에서 알아가는 중이다.

나중에 메이저 과를 선택하지 않게 된다면, 내 평생 중 이번 인턴 1년 동안이 죽음과 가장 가깝게 지내는 기간이 될 것이다.
특히 요즈음은 세 달째 메이저 과에서 근무하다 보니 환자의 사망을 자주 접하게 된다.
내가 매일 아침마다 히크만 카테터에서 채혈하던 환자분이 돌아가신 뒤, 아직 체온이 남아 있는 상태에서 히크만 카테터를 제거한 경험이 있다.
소생 가능성이 없다는 것을 모두가 알지만, 보호자가 연락되지 않아 새벽 3시부터 한 시간 넘게 심폐소생술을 했던 경험도 있다.

인턴에게 환자의 사망이 가지는 의미

병실에 입원한 환자의 사망 과정은 대개 비슷한 경과를 밟는다.
호흡곤란, 심박수 이상, 항생제로 조절되지 않는 발열, 혈중 염증수치 증가, 전해질 불균형, 의식저하 등의 징후가 나타난다.
그러다가 어느 순간에 심정지가 발생하면 병원 내에 CPR 방송을 한다.
의료진이 모여 심폐소생술을 시작하고, 심박동이 회복되면 환자를 내과계 중환자실로 이송한다.
그렇지 않은 경우 심박동이 회복되기를 기다리며 심폐소생술을 지속하다가 연락 받고 찾아온 보호자가 심폐소생술 중단에 동의하면 심폐소생술을 중지하고 사망진단을 내린다.

이러한 과정을 인턴의 관점으로 본다면 다음과 같다.
혈액배양과 동맥혈 채혈을 동시에 시행하게 되는 환자가 있거나, 채혈, 관장, 심전도 검사를 자주 시행하게 되는 환자가 있으면 미리 마음의 준비를 해둔다.
그러다가 언젠가 “솔시~레솔 솔시~레솔, 솔시~레솔 솔시~레솔”로 시작하는 다급한 CPR 방송 알람이 울리면 당장 몇몇 환자들의 얼굴들이 떠오른다.
이어지는 CPR 방송에서 “CPR팀 00병동, CPR팀 00병동, CPR팀 00병동, CPR팀 00병동” 소리를 듣고 해당 병실로 달려가 보면 예상했던 환자에 대해 심폐소생술이 진행중이다.
장갑을 끼고 기다리다가 자신의 차례가 되면 심장마사지를 시작한다.
환자의 심박동이 회복되면 그 환자를 담당하는 인턴이 앰부백을 짜면서 내과계 중환자실로 이동한다.
심박동이 회복되지 않고, 심폐소생술 중단에 보호자가 동의하여 사망 진단이 내려지면, 그 환자를 담당하는 인턴이 히크만 카테터, 소변줄 등을 제거하게 된다.

요약하건대, 인턴에게 환자의 질병과 죽음의 사이에는 CPR(심폐소생술)이 있다.

DNR

가끔씩은 CPR 방송 없이 환자가 사망했으니 카테터를 제거해달라는 연락만 병동에서 인턴에게 오는 경우도 있다.
이는 심정지가 발생하기 이전에 환자가 CPR을 원치 않는다고 미리 의사를 표현했기 때문이다.
이를 심폐소생술 거부, 또는 DNR(Do not resuscitate)이라고 부른다.
또는 단지 CPR을 거부하는 것 이외에도, 영양공급, 혈액투석, 수혈, 혈액검사, 항암치료 등에 관해 선택할 수 있는 포괄적인 내용의 사전의료의향서를 작성하는 경우도 있다.

CPR의 의미

심정지가 찾아온 환자에게 CPR을 시행해 자발적인 심박동이 회복되더라도 대부분 그 상태는 오래 지속되지 못한다.
의식 없이 심장만 뛰는 상태로 몇 시간을 버티다가 결국 다시 심정지가 발생한다.
처음 CPR을 할 때에는 환자의 심박동이 돌아온 것만으로도 보람을 느끼기도 했지만, 여러 환자에게 CPR을 시행해 보고 그 장기적인 경과가 좋지 않은 것을 알게 되니 CPR을 하면서도 회의감이 들었다.
심정지는 한밤중에 발생하는 경우가 많고, 인턴이 하는 술기들 중 가장 힘든 것이 흉부압박인데다, 한 번 CPR을 시작하면 대개 20분 이상씩은 하기 때문에 CPR을 하고 나면 몸이 지친다.
결국 결과가 좋지 않을 것임을 알면서도 몸이 힘든 일을 해야 하니 마음도 지치게 된다.
이 CPR을 왜 하는 것인가? 하는 의문이 생기는 것도 당연한 것이다.

이 질문에 대해 누군가는 죽음을 맞는 환자에 대한 예의라고 대답한다.
죽음을 맞을 때에 환자 혼자서 쓸쓸히 맞이하는 것이 아니라 수많은 의사, 간호사가 환송해주도록 한다는 것이다.
살아날 가망이 없는 환자라도 적어도 30분은 흉부압박을 해야 예의가 아니겠냐고 주장하며, 일부러 사전에 DNR을 받지 않는 사람도 있다.
물론 나는 그러한 주장을 하는 사람이 새벽 3시에 잠에서 깨어 혼자 흉부압박을 해보고 나면 더 이상 그런 얘기를 하지 않을 것이라고  생각한다.

비슷한 대답이지만 나는 CPR이 갑작스럽게 죽음에 마주친 환자가, 가족 곁에서 죽음을 맞을 수 있도록 시간을 벌어주는 과정이라고 생각하게 되었다.
한편으로는, 환자의 죽음을 예측하지 못해 미리 DNR을 받는 등 환자와 보호자에게 마음의 준비를 하도록 하지 못한 의료진에게 책임을 묻는 일종의 벌이라고도 느꼈다.

물론 짧은 기간에 몇 번 CPR을 해 보았다고 해서 내가 심폐소생술은 물론이고, 삶과 죽음의 문제를 제대로 이해하게 된 것은 아니다.
그러나 그것들이 의미하는 바가 무엇인지를 한 번 더 고민해 보게 되고, 교과서로부터 머리로 받아들인 추상적이고 뜬구름 잡는 것 같은 개념이 아니라, 가슴과 온몸으로 보다 생생하고 구체적으로 받아들이는 데에 한 걸음 나아갔다고 느끼게 되었다.
보다 구체적으로 말한다면, “환자의 생명을 살리는 의사”라는 말은 나에게 인턴이 된 이후에 더욱 뼈저리고 가슴 뭉클하게 와닿고 있다.
아직은 느끼고 배우고 자라야 할 점이 더 많다고 매일 생각한다.

3줄 요약

  1. CPR은 심정지 환자에게서 심박동을 회복시키기 위한 목적으로 시행한다.
  2. 인턴에게 환자의 죽음은 CPR을 의미한다.
  3. CPR의 의미를 고민하는 과정을 통해 깨닫고 배우는 점들이 있다.

관련 포스트

암센터 간담췌암외과 인턴 후기

서울대병원 본원에서의 3개월간의 인턴 근무를 마치고 6월부터 3개월간은 일산에 있는 국립암센터에 파견되었다.
6월에는 간담췌암외과(일반외과), 7월에는 자궁암외과(부인과), 8월에는 마취과에서 근무하게 되었다.
5월 31일 오후 6시에 본원에서 퇴근한 뒤에 짐을 챙겨서 택시를 타고 국립암센터로 왔다.

암센터에 도착해서 처음으로 신기했던 것은 당직실이었다.
넓고 쾌적할 뿐 아니라 TV, 정수기 등의 장비들이 잘 갖추어져 있었기 때문이었다.

당직실에 감탄하고 있던 것도 잠시, 얼마 지나지 않아 CPR 방송이 나왔다.
나는 오프였기 때문에 CPR에 갈 필요는 없었고, 이곳의 CPR 방송이 신기하다는 생각을 하면서 방송을 듣고 있었다.
CPR 방송이 너무나 평온했기 때문에 놀랐고, CPR 방송을 단지 2번만 반복해서 해주고 끝났기 때문에 놀랐다.

전산팀에 방문하여 새로 공인인증서를 발급받아 EMR에 접속해서 로그인해 보니 친숙한 화면이 나를 반겼다.
EMR에 새로 적응하기 위해서 고생할 필요가 없다는 점이 다행이라고 생각되었다.

그렇게 지나간 암센터에서의 첫날 이후 한 달 동안 암센터 간담췌암외과에서 일하면서 몇 가지 불편한 점들을 발견할 수 있었다.
우선 중앙계단이 없어 한두 층을 직접 계단으로 이동하는 것이 불편했다.
특히 당직 시간에 5층(폐혈액종양내과)과 7층(간담췌암외과)을 빈번하게 오가는데 단지 두 층을 이동하기 위해 매번 엘리베이터를 기다렸다가 타야 하는 점이 귀찮게 느껴졌다.
또한 ABGA용 주사키트가 따로 준비되어 있지 않아 매번 1cc 주사기에 직접 헤파린을 코팅하는 과정을 거쳐야 한다는 점이 불편했다.

그러나 그 외에는 별다른 불편한 점이 없었다.
주사기의 종류, 일회용 멸균장갑의 종류, 수술장의 구조 등은 본원과 달라서 처음에 적응하는 데에 시간이 필요했다.
그러나 익숙해지고 난 뒤에는 오히려 본원보다 편하게 느껴졌다.

지난 한 달을 돌아보면 암센터 간담췌암외과에서의 인턴 근무는 편하다고는 할 수 없었다.
몸과 마음이 함께 지쳐가는 것을 느낄 수 있었지만 그만큼 많은 것들을 배울 수 있었다는 점에 만족한다.
칭찬을 통해서 한 가지를 배우고 꾸중을 통해서는 두 가지를 배울 수 있었던 지난 한 달이었다.

관련 포스트

인턴 하기 힘든 날

역치가 높아서 그런지, 지금까지 세 달 째 인턴 생활을 하면서 힘들다고 느꼈던 날은 단 하루뿐이었다.
4월 중 이비인후과 수술이 익일 6A에 끝났던 날이 그날이었다.
그날 이외에는 인턴이 할 일이 많기는 해도 견딜 만은 하다고 생각하면서 지냈다.

근래에 인턴 생활이 힘들다고 느낀 날이 하루 더 생겼다.
이틀 전 11층 당직(101, 111, 112, 114 병동)을 하던 날이었다.
11층 당직을 서는 날의 인턴의 수면 시간을 결정하는 것은 대개 혈액배양 환자수이다.
혈액종양환자들은 대개 히크만 카테터를 가지고 있고, 이들에게서 열이 날 경우 말초 2쌍과 히크만 2쌍, 총 4쌍(8병)짜리 혈액배양 검사를 시행하게 된다.
준비하고 채혈하고 정리하는 과정이 복잡하고 시간이 오래 걸리기 때문에 혈액배양 환자수가 많으면 그만큼 잠 잘 시간이 줄어드는 것이다.
그러나 이날 밤에는 혈액배양을 한 사람의 숫자가 5명 정도로, 많은 편은 아니었다.
그럼에도 불구하고 이날 당직이 힘들었던 이유는 갑자기 전신 상태가 악화된 사람이 생겼기 때문이다.

자발 호흡이 없거나 매우 약할 정도로 환자의 상태가 나쁜 경우, 중환자실로 이동하기 전까지는 수동식 인공호흡기(앰부 백)를 적용해야 한다.
이 경우 앰부 백을 짜는 일은 주로 인턴의 몫이다.
앰부 백을 짜는 일은 힘든 편은 아니지만, 그 동안에 쉴 수 없는데다 다른 일을 전혀 할 수 없기 때문에 일이 쌓이게 되는 것이 문제다.
그동안 내과에서 당직을 서는 동안에 내가 앰부 백을 짜야 하는 환자는 한 번도 없었다.
그러다가 이날 밤에는 환자 두 명이나 앰부 백을 짜야 했다.

한 환자는 밤 10시 경에 상태가 악화되었다.
혈액 검사를 비롯한 각종 검사를 하고 조치를 취한 이후에도 상태가 호전되지 않아 11시부터는 앰부 백을 짜면서 내과계 중환자실까지 이동했다.
그런 뒤에 그동안 쌓였던 소독, 채혈, 혈액배양 검사, 관장, 청결 간헐 도뇨, 비위관 삽입 및 세척 등의 일을 했다.
일들을 마무리하고 나니 3시 반경이 되었다.
원래의 목표가 3시에 잠드는 것이었다가 30분 정도 늦어진 것이라 이정도도 나름 괜찮다는 생각으로 잠이 들었다.

그러나 30분 정도 잠을 자던 중 콜을 받고 잠에서 깼다.
케모포트 바늘 교환, 심전도 검사 등의 할일이 생겼기 때문이었다.
그런 일들을 마무리하고 5시 경에 잠자리에 들려는데 갑자기 상태가 악화된 환자가 생겼다는 전화를 받았다.
그 환자에게서 각종 검사를 위한 채혈을 하고 응급 CT 검사에 동반하여 다녀왔다.

그런 뒤 잠을 잘까 하다가 이왕 이렇게 된 김에 내 담당 병동에서 할 정규 채혈을 준비하기로 했다.
당직은 7시까지 서야 하는데 내가 맡은 병동의 정규 채혈은 6시부터 시작해야 했기 때문에 미리 준비해두기 위해서였다.
그러나 정규 채혈 준비를 시작한지 얼마 지나지 않아 그 환자의 상태가 더욱 악화되어 앰부 백을 짜러 와야 한다는 콜을 받았다.
5시 반부터 앰부 백을 짜기 시작해서 아침 7시에 당직이 마칠 때까지 계속해서 앰부 백을 짰다.
당직을 마치고 정규 근무가 시작되었는데, 밤새 잠을 30분밖에 자지 못한 것도 문제였지만 6시부터 해야 할 정규 채혈을 하나도 하지 못한 상태라는 것이 더 큰 문제였다.
정신이 반쯤 나간 상태로 허겁지겁 정규 채혈, 처방 입력, 동의서 받기, 소독 등의 일을 해두고 당직실에서 1시간 정도 눈을 붙인 뒤에 다시 골수 검사 보조를 하러 병동에 갔다.
급한 일들을 어느 정도 마무리하고 나니 정오가 다 되었다.

감기에 걸려 몸이 아픈 상태에서 배도 고프고 잠도 부족한 것이 겹치니 힘들었다.
마지막 식사 후 15시간만에 먹는 병원식당의 모밀국수가 그렇게 반가울 수 없었다.

이렇게 하루를 보내고 나니 환자가 건강하기를 인턴이 얼마나 간절히 바라는지 느끼게 된다.
환자가 아프면 환자만 고생하는 것이 아니다.
가장 고생하는 사람은 물론 환자이지만, 보호자, 주치의, 간호사, 인턴 모두가 고생을 하게 된다.
이유는 다르더라도, 인턴은 환자가 건강하기를 진심으로 바란다.
열이 나지 않기를 바라고, 가슴이 아프지 않기를 바라고, 숨쉬는 것이 불편하지 않기를 바라고, 수액 들어가는 팔이 붓지 않기를 바라고, 변을 제때 잘 보기를 바라고, 소변을 잔뇨 없이 스스로 잘 보기를 바라고, 식사를 입으로 잘 하기를 바라고, 욕창이 생기지 않기를 바란다.
그러나 그렇게 건강한 사람은 병원에 입원할 리가 없다는 게 함정이다.

관련 포스트