대부분의 안드로이드 어플리케이션은 두개 이상의 Activity로 이루어진다. 각 Activity 들은 서로 Intent 를 통해서 통신을 하게된다.

이번 포스트에서는 Activity 간에 통신하는 방법을 예제와 함께 알아보자.

 

먼저 가장 메인 화면 레이아웃은 아래와 같이 구성한다.

 

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">
    <TextView
        android:layout_height="wrap_content"
        android:id="@+id/textView"
        android:textSize="10pt" android:text="display"
        android:layout_width="wrap_content"
        android:layout_gravity="center"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:id="@+id/openBtn"
        android:text="open"/>
</LinearLayout>

 

새로운 Activity 를 위해서 아래와 같은 레이아웃을 하나 더 추가한다.

 

파일명은 form.xml 로 하고 내용은 아래와 같다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:orientation="vertical">
    <EditText
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:layout_width="fill_parent"
        android:hint="enter text"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="OK" android:id="@+id/okBtn"/>
</LinearLayout>

 

위 레이아웃을 보면 어느 정도 눈치 채겠지만 프로그램에 대해서 설명하자면 두 번째 레이아웃에 텍스트를 입력하고

OK 버튼을 누르면 첫 번째 레이아웃에 표시되는 것이다.

먼저 main.xml 과 연결되어 있는 MainActivity 를 만들도록 하자.

package net.cranix.android.activitytest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button openBtn = (Button)findViewById(R.id.openBtn);
        openBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(MainActivity.this,FormActivity.class);
                startActivityForResult(i, 0);

            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == 0) {
                TextView textView = (TextView)findViewById(R.id.textView);
                textView.setText(data.getExtras().getString("text"));

            }
        }
    }
}

위 소스에서 굵게 표시한 부분이 중요한 부분이다.

먼저 첫번째 부분은 Intent 를 이용하여 다른 Activity 를 호출하는 코드이다. 여기서 Intent는 안드로이드내 의 모든 Activity 간의 통신을 담당하는 구조체다. Intent 는 위와 같이 new Intent([호출한Activity],[호출당한Activity]) 형태로 만든다.

startActivityForResult 함수는 인텐트와 함께 resultCode 를 다른 Activity 로 보내는 역할을 한다 여기서 resultCode 가 어떤 역할을 하는지는 계속 읽다보면 이해 할 수 있을것이다.

 

 

다음으로 form.xml 과 연결될 Activity 를 만들어 보자.

 

아래와 같이 AndroidManifest.xml 파일을 열어 Application 탭의 Add 버튼을 누른다.

 

다음에 나오는 대화상자에서 Activity 를 클릭하면 아래와 같이 오른쪽에 Activity 설정 대화상자가 나온다.

거기서 아래와 같이 오른쪽에 있는 name 을 클릭하자

 

그럼 아래와 같이 클래스 추가하는 대화상자가 나오는데 Name 에다가 FormActivity 을 넣고 클래스를 생성한다.

 

 

소스는 아래와 같다.

package net.cranix.android.activitytest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class FormActivity extends Activity {
    private EditText editText;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.form);

        editText = (EditText)findViewById(R.id.editText);
        Button okBtn = (Button)findViewById(R.id.okBtn);
        okBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = getIntent();
                i.putExtra("text", editText.getText().toString());
                setResult(RESULT_OK, i);
                finish();

            }
        });
    }
}

 

이번 소스에도 중요한 부분은 볼드체로 되어있다.

현재 Activity 가 떠 있다는 소리는 어떤 Intent 에 의해서 호출되어진 것을 의미한다.

getIntent() 함수는 호출한 Intent 를 돌려주는 함수이다.

Intent 에다가는 데이터를 저장할 수 있는 이렇게 데이터가 저장된 intent 를 다른 Activity 로 보냄 으로서 통신이 이루어 지는 것이다.

데이터를 저장하는 방법은 위와 같이 intent 의 putExtra([key],[value]) 함수를 사용하면 된다.

setResult 함수는 호출한 Activity 에 전달해줄 intent 를 저장하는 함수로서 resultCode 와 같이 사용한다.

마지막으로 finish() 함수가 호출되면 setResult 함수에 의해 저장되어있던 resultCode 와 intent 가 이전의 Activity 에 전달되면서 현재의 Activity 는 닫히게 된다.

이러한 방식은 html 의 form 전달 방식을 보는듯 하다.

 

그럼 완성된 어플리케이션 화면을 보도록 하자.

 

 

사실 이 어플리케이션에서 Intent 를 쓰지 않고도 같은 기능을 하도록 만들 수 있다. 그럼에도 구지 Intent 를 쓰는 이유는 다른 어플들과의 통신을 쉽게 하기 위해서 이다.

안드로이드 내의 모든 어플들은 Activity 단위로 되어있으며 이 모든Activity 는 AndroidManifest 파일에서 허용만 해주면 다른 Activity 가 끌어다 쓸 수 있게 되어있다.

이러다 보니 수많은 사람들이 만든 Activity 들간의 통신방법이 존재 할 수 있기 때문에 이러한 통신 방법을 통일할 필요가 있었던 것이다.

 

 

'알짜정보 > Android' 카테고리의 다른 글

android 소스 다운로드 받기  (0) 2010/03/18
goldfish 커널 다운로드 및 컴파일 하기  (0) 2010/03/16
android 커널부팅부터 액티비티까지  (0) 2010/03/12
AlertDialog 와 Toast  (0) 2010/03/01
SharedPreferences  (1) 2010/03/01
Activity 간의 통신  (0) 2010/02/25
Posted by cranix

개요

Java 어플리케이션을 배포하는 새로운 방식인 JNLP 를 테스트 해 보도록 한다.

 

테스트 프로그램

<DayTime.java>

package net.cranix.daytime.model;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class DayTime {
    /**
     * DayTime 서버로부터 결과를 받아서 돌려주는 함수
     * @param server
     * @return
     * @throws IOException
     * @throws UnknownHostException
     */
    public String getRemoteTime(String server) throws UnknownHostException, IOException {
        StringBuffer sb = new StringBuffer();
        BufferedReader br = null;
        try {
            Socket sock = new Socket(server,13);
            br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            String line = null;
            while((line = br.readLine()) != null) {
                sb.append(line).append("\n");
            }
        }
        finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString().trim();
    }

}

 

<MainFrame.java>

package net.cranix.daytime.view;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import net.cranix.daytime.model.DayTime;

public class MainFrame extends JFrame {
    private JLabel label = null;
    private JButton closeBtn = null;
    private JButton reloadBtn = null;
    private DayTime model = null;
    public MainFrame(DayTime model) {
        super();
        this.model = model;
        init();
        updateTime();
    }
    public void updateTime() {
        try {
            label.setText(model.getRemoteTime("time.nist.gov"));
            pack();
        } catch (UnknownHostException e) {
            JOptionPane.showMessageDialog(this, e);
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, e);
        }
    }
    public void init() {
        // 이벤트 처리
        label = new JLabel("TimeLabel");
        reloadBtn = new JButton("Reload");
        reloadBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                updateTime();
            }
        });
        closeBtn = new JButton("Close");
        closeBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                dispose();
            }
        });
        // 컴포넌트 배치
        JPanel btnPanel = new JPanel();
        btnPanel.add(reloadBtn,BorderLayout.EAST);
        btnPanel.add(closeBtn,BorderLayout.WEST);
        getContentPane().add(label,BorderLayout.CENTER);
        getContentPane().add(btnPanel,BorderLayout.SOUTH);
        // 프레임 설정
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("DayTime");
        setResizable(false);
    }
}

 

<Main.java>

package net.cranix.daytime;

import net.cranix.daytime.model.DayTime;
import net.cranix.daytime.view.MainFrame;

public class Main {
    public Main() {
        DayTime model = new DayTime();
        MainFrame view = new MainFrame(model);
        view.setVisible(true);

    }
    public static void main(String args[]) {
        new Main();
    }
}

 

 

JNLP XML 설정

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="file:///E:/cranix/workspace/DayTime">
    <information>
        <title>DayTime</title>
        <vendor>cranix</vendor>
        <homepage href="http://cranix.net" />
        <description>demo daytime</description>
        <offline-allowed/>
    </information>
    <security>
        <all-permissions/>
    </security>
    <resources>
        <j2se version="1.2+" />
        <jar href="DayTime.jar"/>
    </resources>
    <application-desc main-class="net.cranix.daytime.Main" />
</jnlp>

 

jar 파일 서명하기

keytool –genkey –keystore cranixKeystore –alias cranix

keytool –selfcert –alias cranix –keystore cranixKeystore

keytool –list –keystore cranixKeystore

jarsigner –keystore cranixKeystore DayTime.jar cranix

 

 

실행하기

생성한 jnlp 파일을 더블클릭

image

'알짜정보 > Java' 카테고리의 다른 글

JNLP 테스트  (0) 2010/02/14
JAVA 리눅스 IP 주소 알아내기  (0) 2008/12/02
apache 프로젝트의 commons-dbcp 를 이용하여 connection pool 만들기.  (0) 2008/08/15
java 에서 xmlrpc 사용하기  (0) 2008/07/13
annotation 주석?  (0) 2006/12/16
JAVA5(1.5) 달라진점!  (0) 2006/12/16
Posted by cranix
TAG Java, jnlp, 배포
언제나 궁금했었는데 역시나 찾아보니까 나온다.
trunk - 소스의 주 개발 작업을 진행하는 폴더
branches - 소스의 실험적인 작업을 진행하는 폴더, 소스의 현재 버전을 유지보수 하고, 현재 버전을 기반으로 차기 버전을 개발할 경우 이 폴더 이용
tags - 현재 릴리즈된 소스를 관리하기 쉽게 따로 보관하는데 사용. 즉, 개발을 위한 것이 아니라 보관을 위한 것이기 때문에 export만 해야 한다. 체크아웃하여 커밋 할 경우 경고 메시지가 출력된다.

출처 - http://blog.naver.com/ziugae80?Redirect=Log&logNo=88242569

Posted by cranix
오늘 이런 글을 보았다.
스티브 워즈니악(Steve Wozniak)은 사실 애플 매니아들에게는 잡스보다 더 존경을 받는 사람입니다(저는 80년대초 애플을 처음 알게 된 때부터 워즈니악을 더 좋아했습니다). 그 사람이 최근 자서전을 냈습니다. 제목이 재미있습니다. "iWoz: From Computer Geek to Cult Icon: How I Invented the Personal Computer, Co-Founded Apple, and Had Fun Doing It". 읽으면 "나는 옛날에..."(I was)랑 똑같이 들립니다.


워즈니악은 말합니다. 자신의 설계 철학은 "자신이 사용하고 싶은 것은 창조하라"(Create what you want to use)라고. (가이 가와사키와의 인터뷰에서)

제가 워드 커닝햄에게 물었습니다. 당신 같이 위대한 프로그래머가 되려면 어떻게 해야 하나요?
저는 작지만 유용한 프로그램들을 매일 작성할 것을 추천합니다. 누군가가 똑같거나 혹은 더 나은 걸 이미 만들었다는 데에 절대 신경쓰지 마세요. 유용성과 복잡성 간의 균형 감각을 얻기 위해서는 당신 자신이 만든 프로그램의 유용성을 직접 느껴봐야만 합니다. --워드 커닝햄


정말 감동적인 말입니다. 그는 크고 불필요한 설계를 가끔 생각해볼 것을 추천하지 않았습니다(Write Small But Useful Programs Everyday를 다 반대로 뒤집은 말입니다).

계속 개선하면서 최소 1년 이상 써오고 있는 자작 프로그램이 있습니까? 만약 그렇지 못하면서, 남들이 1년 이상 써줄 프로그램을 만들 것이라 기대한다는 것은 어딘가 좀 이상하지 않습니까?

저는 프로그래머를 뽑을 때 다음과 같은 질문들은 꼭 하려고 합니다:

  • 업무상 의무적으로 만들어야 하는 프로그램은 아닌데, 자신의 업무를 보조하기 위해 만들어 쓰는 프로그램으로 어떤 것이 있습니까?
  • 업무 외로 자신의 삶을 위해 프로그래밍해 쓰는 것이 있다면?
  • 올해 들어 자신을 위해 만든 프로그램이 몇 가지인가요?
  • 자신이 가장 가치를 느끼는(혹은 느꼈던) 자작 프로그램을 보여주세요.

자신이 직접 사용자의 역할을 해본 프로그래머들은 단순함의 가치를 알고 있습니다. 그 사람들은 어떤 소프트웨어가 진정한 가치를 주는지 몸으로 알고 있습니다. 다른 프로그래머들이 1000줄에서 얻을 가치를 이 사람들은 10줄에서 얻어 냅니다. (하지만 계속 뭔가 자기를 위해 만들어 내지만 완성한 것도 드물고, 또 1년 이상 개선시켜 가며 써본 것이 하나도 없는 프로그래머라면 이야기가 다릅니다.)


여러분은 오늘 자신을 위해 무엇을 프로그래밍 하셨습니까?


출처 : http://agile.egloos.com/2807583


이 글을 본 다른 여러 개발자의 반응과 마찬가지로 나역시 부끄러움을 느꼈다.

난 프로그래밍을 좋아한다.
저 글을 보면서 내가 진짜 좋아하는건 프로그래밍인가?
라는 의문을 느낀다.

그래서 좀 더 깊이 생각해보기로 했다.
먼저 프로그래밍의 좋은점을 생각해 보자.

가장 먼저 내가 한 프로그래밍에 의해 결과물이 나왔을때
그 성취감은 말로 표현할 수 없다.
그럴때는 코드를 아무리 보고있어도 지루하지 않았다.

또하나 좋은점은 그런 코드를 남이 보고 그걸 알아줄때 이다.
이럴때에도 뿌듯함을 느낀다.
어떤책에서 인정중독 에 대해서 읽은적이 있다.
그걸 읽으면서 정말 내얘기라고 공감했었는데 그게 이런데 나타난다.

물론 좋은점만 있는것은 아니다.
그렇다면 싫은점은 무엇일까?

내가짜지않은 코드를 본의아니게 이해 해야 할 때 스트레스를 받는다.
사실 프로그래머라면 반드시 해야하는 일이겠지만 이일은 나에게있어 스트레스다.

또 한가지는 어떤 프로젝트의 프로그래밍을 처음 시작할때 막막한 답답함을 느낀다.
이것이 정리되어 간다는 것을 느낄 때에는 다시 쾌감을 느끼지만 그 전 까지는 답답함의 연속이다.

개발자는 새로운 기술에 대해서 두려워 하지않고 공부 할 수 있는 마음가짐이 필요하다고 생각한다.
그리고 나는 두려워하지 않는다고 생각해 왔었다.
그러나 이렇게 조금만 깊이 생각해 보니 그 생각은 그저 자기보호 본능에 의해서 나온것 이었다.

나는 두려워 하고있었다.
새로운 기술을 또... 새로운 변화를...


"하지만 계속 뭔가 자기를 위해 만들어 내지만 완성한 것도 드물고, 또 1년 이상 개선시켜 가며 써본 것이 하나도 없는 프로그래머라면 이야기가 다릅니다."

위 글에서 이 말이 자꾸 걸린다.
나를 위해서 만든 프로그램이라면 그래도 몇가지 있긴하다.
그러나 그걸 쓴 적은? 없다.
왜냐하면 완성 했을때의 그 희열감을 느끼고 나면 다른 무언가를 다시 찾기 때문이다.
그리고 그때부터 그 프로그램은 방치 상태가 된다.
업그레이드가 전혀 안 되는 것이다.

그러고는 또 다른걸 만든다.
이러다 보면 만들다 중도에 포기하는 것도 많이 있다.
그러고는 접어두고.. 이러고를 반복하다 보면 시작하기가 두려워진다.
다시 시들해 질까봐…
 
오늘은 다시 시작해보자 작은것부터….

'자유글 > 생각' 카테고리의 다른 글

나에게 있어 프로그래머란?  (2) 2010/02/09
내 꿈은 무엇일까?  (0) 2008/04/11
평상시란 없다.  (4) 2007/06/14
머리가 뜨겁다  (0) 2007/03/07
사람풍경  (0) 2007/02/23
내가 어렸을땐..  (0) 2007/02/03
Posted by cranix
우분투 터미널에서 글자가 겹쳐나올때

# apt-get install xfonts-terminus
# fc-cache -r
터미널의 프로파일에서 폰트를 terminus로 변경

Posted by cranix
TAG terminus
export LC_ALL=ko_KR.UTF-8
export LANG=ko_KR.UTF-8

'알짜정보 > Linux server' 카테고리의 다른 글

cent os 기본정보 확인  (0) 2010/12/30
리눅스 설치기  (0) 2010/03/17
ubuntu 터미널 한글깨질때  (0) 2010/02/01
ubuntu 오픈오피스 글자 깨질때  (0) 2010/02/01
fedora 10 에다가 vncserver 설치하기 (수정)  (0) 2009/08/10
apache 에 svnserver 연동하기  (0) 2009/08/07
Posted by cranix
TAG ubuntu, 한글
다음명령을 시행하여 준다.

gksu rm /etc/fonts/conf.d/29-language-selector-ko-kr.conf

Posted by cranix