[ kotlin ] TIL; Intent

from.k·2023년 12월 5일
1

Mobile-Software

목록 보기
1/15
post-thumbnail

애플리케션들은 한 개 이상의 액티비티들로 구성되어 있으며, 애플리케이션 안에서 액티비티들은 느슨하게 연결되어있다.

첫 번째 액티비티에서 두 번째 액티비티로 전화하려면? intents 이용
Intents are the messageing system by which onen activity is able to launch another activity.

An intent is an abstract description of an operation to be performed.

  • startActivity to launch an Activity
  • sendBroadcast to send it to any interested BroadcastReceiver components
  • starService(Intent) or
  • bindService(Intent, ServiceConnection, flags) to communication with a background Service

intent 객체에 bundle 타입 data 를 전달할 수 있다.



Intent 종류

  • Explicit intent 명시적 인텐트
    구체적으로 지정
    "애플리케이션 A의 컴포넌트 B 를 작동시켜라"

  • Implicit intent 암시적 인텐트
    기본 조건만 지정
    "지도를 보여줄 수 있는 컴포턴트라면 어떤 거라도 괜찮아!"



1. SubActivity 생성


2.

Manifest 파일에 컴포넌트에 관한 상세 정보를 등록

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.intentsample">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.IntentSample">
      
      <!-- App. 에 등록된 2개의 컴포넌트 => 모두 액티비티 -->
        <activity
            android:name=".SubActivity"
            android:exported="true" />
      <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
              	<!-- MainActivity 를 가장 먼저 실행 -->  
                <action android:name="android.intent.action.MAIN" />
				<!-- 바탕화면에 App.Launcher Icon 으로 나타나야함 -->  
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>



3. Explicit intent

실행하고자 하는 액티비티 이름을 지정
this => MainActivity
SubActivity::class.java
=> 메모리에 저장된 섭액티비티 클래스를 가리킴. 즉, 섭액티비티 클래스 정보를 추출할 때 시작점이 됨 : reflection

var intent = Intent(this, SubActivity::class.java)
startActivity(intent)


  • MainActivity
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.button.setOnClickListener {
            val intent = Intent(this, SubActivity::class.java)
            startActivity(intent)
        }
    }

  • SubActivity
class SubActivity : AppCompatActivity() {
    private lateinit var binding: ActivitySubBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySubBinding.inflate(layoutInflater)
        setContentView(binding.root)
		
        // Activity stack 에서 SubActivity 제거
        // -> MainActivity 가 스택에서 사라지지 않는 이상 다시 활성화
        binding.button.setOnClickListner {
        	finish()
        }
   }
}



Extra 속성을 사용한 데이터 전달

Extra : intent 에 포함되어 전달되는 데이터

  • key-value 쌍의 형태로 Extra 에 추가
  • Key 만을 사용해 value 을 가져오기 떄문에 value 의 타입을 알아야함
  • 데이터 전달
intent.putExtra()
  • 데이터 받기
intent.getInExtra(key, value)

  • MainActivity
// 클래스 밖에서 선언한 문자열
// SubActivity 에서도 참조 가능
const val MY_STRING = "my_string"
const val MY_INT = "my_int"

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.button.setOnClickListener {
            val intent = Intent(this, SubActivity::class.java)
            val str = binding.editText.text.toString()
            
            // Intent 객체에 메시지를 포함해 전달 
            intent.putExtra(MY_STRING, str)
            intent.putExtra(MY_INT, 13)
            startForResult.launch(intent)
        }
    }

  • Subactivity
class SubActivity : AppCompatActivity() {
    private lateinit var binding: ActivitySubBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySubBinding.inflate(layoutInflater)
        setContentView(binding.root)     
        
		// if 조건문이 null 이면,
        // Extra 에서 String 과 Int 값을 가져옴
        if (intent.extras == null || intent == null) return
         val qString: String? = intent.getStringExtra(MY_STRING)
         val qInt: Int = intent.getIntExtra(MY_INT, 0)
         binding.editText.setText(qString + qInt.toString())
         
         
         // 위의 코드 블록과 같은 내용
		// 인텐트 객체가 부가 메시지를 포함하는지 확인
        if(intent.hasExtra(MY_STRING) && intent.hasExtra(MY_INT))
        {
        	// Elvis 연산을 사용한 Null safe 검사
            // extras 의 타입은 Bundle 로 getString() 사용
            val extras: Bundle? = intent.extras ?: return
            val qString = extras?.getString(MY_STRING)
            val qInt = extras?.getInt(MY_INT)
            binding.editText.setText("$qString $qInt")
        }

        binding.button.setOnClickListener {
           finish()
        }
    }
}

 if (intent.extras == null || intent == null) return
val extras: Bundle? = intent.extras ?: return
extras = intent.extras if intent.extras != nullextras = null if intent.extras == null



Activity 로부터 결과 돌려받기

액티비티 사이의 작업은 양방향 작업


  • MainActivity

startForResult.launch(intent) -> 단순히 액티비티 전환이 아닌 결과를 돌려받기 위한 액티비티 호출
startForResult -> 결과 돌려받았을 때 처리할 메소드 정의

package com.example.intentsample

import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContracts
import com.example.intentsample.databinding.ActivityMainBinding

const val MY_STRING = "my_string"
const val MY_INT = "my_int"
const val RETURN_MESSAGE = "com.example.intent sample.RETURN_MESSAGE"

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.button.setOnClickListener {
            val intent = Intent(this, SubActivity::class.java)
            val str = binding.editText.text.toString()
            intent.putExtra(MY_STRING, str)
            intent.putExtra(MY_INT, 13)
            startForResult.launch(intent)
        }
    }

    private val startForResult = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult(),
        object : ActivityResultCallback<ActivityResult> {
            override fun onActivityResult(result: ActivityResult?) {
                if (result?.resultCode == Activity.RESULT_OK) {
                    if (result.data != null) {
                        val extras: Bundle? = result.data!!.extras
                        val returnStr =
                            extras?.getString(RETURN_MESSAGE) ?: ""
                        binding.editText.setText(returnStr)
                    }
                }
            }
        }
    )
}

  • SubActivity
package com.example.intentsample

import android.app.Activity
import android.content.Intent
import android.os.Build.VERSION_CODES.M
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.intentsample.databinding.ActivityMainBinding
import com.example.intentsample.databinding.ActivitySubBinding

class SubActivity : AppCompatActivity() {
    private lateinit var binding: ActivitySubBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySubBinding.inflate(layoutInflater)
        setContentView(binding.root)

        if (intent.extras == null || intent == null) return
        /*
         val qString: String? = intent.getStringExtra(MY_STRING)
         val qInt: Int = intent.getIntExtra(MY_INT, 0)
         binding.editText.setText(qString + qInt.toString())
        */
        if(intent.hasExtra(MY_STRING) && intent.hasExtra(MY_INT))
        {
            val extras: Bundle? = intent.extras ?: return
            val qString = extras?.getString(MY_STRING)
            val qInt = extras?.getInt(MY_INT)
            binding.editText.setText("$qString $qInt")
        }

        binding.button.setOnClickListener {
           // 결과를 bundle 객체로 생성 -> Intent 객체에 실어보냄
            val returnStr = binding.editText.text.toString()
            val data = Intent()
            data.putExtra(RETURN_MESSAGE, returnStr)
            setResult(Activity.RESULT_OK, data)
            finish()
        }
    }
}




https://velog.io/@soyoung-dev/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%A1%ED%8B%B0%EB%B9%84%ED%8B%B0-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC

https://pangseyoung.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%A1%ED%8B%B0%EB%B9%84%ED%8B%B0%EA%B0%84-%ED%99%94%EB%A9%B4-%EC%A0%84%ED%99%98-%EB%B0%8F-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC-Intent-Kotlin



0개의 댓글