728x90


모바일 플랫폼은 저성능 CPU,  용량이 작은 메모리, 적은 화면 크기, 배터리 용량 등 제약조건이 있는 환경이다. 따라서 윈도우 기반의 PC/노트북  실행환경과는 프로그램 처리 방식이 다르다.


안드로이드 앱(APP)은 여러개의 Activity들로 구성된다.

안드로이드에서는 앱을 실행시키면 실행되는 단위가 Activity 이다.

하나의 Activity 에서 다른 Activity 를 시작하려면 startActivity()를 호출한다.

안드로이드는 새로운 Activity 가 시작될 때마다 Activity 를 스택에 추가한다. 사용자가 back 키를 누르면 현재 Activity는 스택에서 제거되고 스택에 저장된 이전 Activity로 되돌아간다. 즉, 이전 Activity가 실행 Activity로 복귀된다.


안드로이드 장치에서 사용자와 상호 작용하는 객체(object)는 View 클래스이다.
버튼을 클릭했더니 화면이 바뀐다. 이것은 하나의 Activity 에서 또다른 Activity 로 전환되는 것이다.

안드로이드에서는 Activity 간에 정보 전송을 Intent 라는 메커니즘을 사용하여 한다.

안드로이드는 사용될 Activity 를 AndroidManifest.xml 에 꼭 등록해줘야 한다.

메인 Activity는 자동 등록되지만, 추가한 Activity는 별도로 직접 등록해줘야 한다. (Android Studio 에서는 자동 추가됨)


앱(application) 하나를 만들 때 화면에서 다른 화면으로 데이터가 전송되고 다른 화면에서 데이터를 받는 것을 처리하는 과정을 살펴보자. (테스트 첨부파일은 제일 하단에 있음)


Intent 에는 명시적 인텐트와 암시적 인텐트가 있다.

Intent(Context, Class) 형태는 명시적 인텐트다.


MainActivity.java

 public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.btn01);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,NewActivity.class);
                intent.putExtra("key","값전달 : 90");

                intent.putExtra("age", 32);
                startActivity(intent);
            }
        });
    }
}

 NewActivity.java

 public class NewActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new);

        // startActivity 로 보낸 Intent 를 getIntent 메서드를 호출하여 가져온다.
        Intent intent = getIntent();
        // MainActivity 의 putExtra로 지정했던 key 값
        String key = intent.getExtras().getString("key");

        int age = intent.getExtras().getInt("age");

        TextView textView = (TextView) findViewById(R.id.tv_received);
        textView.setText(key);
    }
}


코드의 실행순서

1. NewActivity 인스턴스가 생성된다.

2. 이 인스턴스가 현재 태스크 스택의 최상단에 푸시된다.

3. 액티비티가 시작되며 포그라운드로 가져온다.




// 화면 하단에 글자가 잠깐 나왔다가 사라지는 기능(Toast)

Toast.makeText(getApplicationContext(), "주소록에 저장되었습니다.", Toast.LENGTH_LONG).show();


// 화면에 나타낼 View를 지정, XML Layout의 내용을 메모리상에 객체화하는 역할

// Activity 화면 전체를 설정하는 역할을 한다.

setContentView(R.layout.activity_main); 


// id가 button1 인 것을 찾아 참조변수 button1 에 저장.

Button button1 = (Button) findViewById(R.id.button1); 


// 무명(anonymous) class로 이벤트를 처리 (이벤트를 처리하는 클래스는 다른 곳에서는 전혀 필요 없음)

button1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(getApplicationContext(), "번호 저장버튼이 눌렸습니다.", Toast.LENGTH_LONG).show();
    }           
});


invalidate();  // View 의 화면을 다시 그리게 하는 메소드



※ 다른 Activity 로 데이터를 보내기만 할 경우에는 startActivity(intent); 메서드를 사용하면 된다.

    응답을 받으려면 startActivity가 아니라 반드시 startActivityForResult를 호출하여 Activity를 실행해야 한다.


MainActivity.java

 public class MainActivity extends AppCompatActivity {

    // requestCode 정의
    public static final int REQUEST_CODE = 101;
    TextView received_text;

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

        received_text = (TextView) findViewById(R.id.tv_received);

        Button button = (Button) findViewById(R.id.btn01);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,NewActivity.class);
                intent.putExtra("key","값전달 : 90");
                startActivityForResult(intent,REQUEST_CODE);
            }
        });
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent intent){
        if(requestCode == REQUEST_CODE){
            Toast.makeText(getBaseContext(), "응답 요청코드:"+requestCode +" ,
            결과코드:"+resultCode, Toast.LENGTH_LONG).show();
            if(resultCode == RESULT_OK){
                String key = intent.getExtras().getString("newkey");
                Toast.makeText(getBaseContext(), "응답 key :"+ key, Toast.LENGTH_LONG).show();
                received_text.setText("응답 key :"+ key);
            }
        }
    }
}

 NewActivity.java

 public class NewActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new);

        // startActivity 로 보낸 Intent 를 getIntent 메서드를 호출하여 가져온다.
        Intent intent = getIntent();
        // MainActivity 의 putExtra로 지정했던 key 값
        String key = intent.getStringExtra("key");

        TextView textView = (TextView) findViewById(R.id.tv_received);
        textView.setText(key);

        Button prevBtn = (Button) findViewById(R.id.btn_replay);
        prevBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {               

                Intent resIntent = new Intent(NewActivity.this,MainActivity.class);
                resIntent.putExtra("newkey","3000");

                // 응답을 하기 위한 메소드
                setResult(RESULT_OK, resIntent);
                finish(); // 현재 화면을 종료(다른 화면을 나타내기 위해)
            }
        });
    }
}



2. 암시적 인텐트

약속된 Action 을 지정하여 안드로이드에서 제공하는 기존 응용 프로그램을 실행하는 것이다.

- 전화번호 입력(Dial)
- 전화 걸기 (Call)
- 오디오 파일 불러오기
- 전화번호부 데이터 불러오기


public void onClick(View v) {
  Intent intent = new Intent(Intent.ACTION_CALL); // 전화를 즉시 걸어주는 기능
  intent.setData(Uri.parse("tel:01067604567"));

  if(intent.resolveActivity(getPackageManager()) != null){

      startActivity(intent);

  }

}



public void onClick(View v) {
  Intent intent = new Intent(Intent.ACTION_DIAL); // 전화번호를 표시만 해주는 기능
  intent.setData(Uri.parse("tel:01067604567"));
  startActivity(intent);
}



public void onClick(View v) {
   Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
   intent.setType("audio/*");
   startActivityForResult(intent, 0);
}


AndroidManiFest.xml 파일에 아래의 퍼미션을 추가해줘야 한다.
<uses-permission android:name="android.permission.CALL_PHONE" />


전화를 거는 동작은 액션으로 ACTION_CALL을 가지고, 전화번호를 입력하는 동작은 액션으로 ACTION_DIAL을 가지며, 두 액션 모두 데이터(Data)로 전화를 걸거나 입력할 번호를 필요로 한다.

보통, 데이터에는 실제 데이터가 아닌 데이터의 주소(URI; Uniform Resource Identifier)가 들어가는데, Dialer, 웹 브라우저, 구글맵 어플리케이션 등에서는 위의 데이터처럼 실제 값을 받게 된다.


다른 어플리케이션 상에 존재하는 Acitivity를 수행 시키고 싶은 경우가 있다.
이런 경우 ComponentName을 이용하여 해당 어플리케이션의 Activity를 호출 가능하다.
ComponentName의 인자로 들어가는 packageName은 패키지명
- 예) com.tistory.link2me.addresschart
ComponentName의 인자로 들어가는 className은 패키지명을 포함하는 클래스명
- 예) com.tistory.link2me.addresschart.MyActivity

Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName name = new new ComponentName(String packageName, String className);
intent.setComponent(name);
startActivity(intent);



3. 배열 데이터를 전달하고 싶은 경우

다른 Activity로 넘길때 데이터를 옮길 수 있게 아래의 코드와 같이 getter, setter가 있는 Value Object를 준비한다.
그리고 직렬화 할 수 있도록 Serializable 상속한다.


public class Person implements Serializable {
    private static final long serialVersionUID = 789722909905522166L;
   
    String name;
    int age;
   
    // 생성자 추가
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
   
    // 마우스 우클릭하여  Source --> Generate Getters and Setters ... 선택 (Eclipse 방법)

    // 마우스 우클릭하여 Generate (Alt + Enter)를 선택하고 Getter, Setter 선택(Android Studio)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }   

}

Serializable(직렬화)는 객체의 내용을 바이트 단위로 변환하여 파일 또는 네트워크를 통해서 스트림(송수신)이 가능하게 하는 것이다.
 - 객체 직렬화를 하기 위해서는 먼저 객체의 Serializable 인터페이스를 구현해야 한다.
 - ObjectInputStream 클래스는 객체를 직렬해제 하는 기능을 제공해 주고 있다.
   . 파일에 저장되어 있는 객체
   . 네트워크를 통해 직렬화되어 전달된 객체
 - ObjectOutputStream 클래스는 객체들을 출력하는 기능을 제공해 주고, 출력 스트림에 출력하기 전에 직렬화를 수행한다.


 보내는

 Activity

 // 보낼 데이터 생성
 Person person = new Person();
 person.setName("홍길동");
 person.setAge(25);

 // 명시적 인텐트 생성 및 보낼 객체 담기
 Intent intent = new Intent(getApplicationContext(), TargetActivity.class);
 intent.putExtra("OBJECT", person);

 // 액티비티 시작
 startActivity(intent);

 받는

 Activity

 Intent intent = getIntent();
 Person person = (Person) intent.getSerializableExtra("OBJECT");


보내는

 Activity

 Intent intent = new Intent(this, ClassB);
 String[] myStrings = new String[] {"test", "test2"};
 intent.putExtra("strings", myStrings);
 startActivity(intent);

 받는

 Activity

 Intent intent = getIntent();
 String[] myStrings = intent.getStringArrayExtra("strings");



마지막으로 새로운 Activity를 작성하면 반드시 AndroidManifest.xml 파일에 등록하여 안드로이드 시스템이 찾을 수 있도록 해야 한다.

Android Studio 에서는 java 파일과 xml 파일을 한꺼번에 생성한 경우에는 AndroidManifest.xml 파일에 자동 등록된다.


----------------------------------------------------------------------------------------------------------------------------------


intent_src.zip


Android Studio 는 main 폴더 파일만 복사하면, 내가 생성하여 연습하는 코드에 붙여넣기가 쉽다.

블로그 이미지

Link2Me

,