[Android] Intent

aramjs·2024년 4월 17일
0

Android

목록 보기
1/3

Intent

  • 컴포넌트를 실행하려고 시스템에 전달하는 메시지
  • 컴포넌트 클래스는 개발자가 코드상에서 직접 생성해서 실행할 수 없다.
  • 시스템에서 인텐트 정보를 분석해서 그에 맞는 컴포넌트를 실행해준다.
  • 외부 앱의 컴포넌트와 연동할 때도 마찬가지이다.

  • startActivity() 함수가 인텐트를 시스템에 전달한다.

  • Intent 생성자의 매개변수는 클래스 타입 레퍼런스 정보이다.

  • AndroidManifest.xml

 <activity
            android:name=".AddActivity"
            android:exported="true" />
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

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

        binding.btnMain.setOnClickListener {
            // 버튼을 클릭하면 인텤트를 시스템에 전달한다.
            // 클래스 타입 레퍼런스 정보를 전달한다.
            val intent = Intent(this, AddActivity::class.java)
            startActivity(intent) // startActivity() : intent를 시스템에 전달한다.
            // 메인에서 startActivity()가 호출되면 인텐트를 안드로이드 시스템에 전달하고
            // 이 시스템은 인텐트를 oncreate() 다른 액티비티에 전달한다.
        }
    }
}
  • AddActivity.kt
class AddActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityAddBinding.inflate(layoutInflater)
        setContentView(binding.root)
        enableEdgeToEdge()

        binding.btnAdd.setOnClickListener {
            finish() //finish되어 현재 액티비티를 종료한다. 이전 스택에 쌓여 있던 액티비티가 표시된다.
            true // 클릭 이벤트 핸들러에서 이벤트 처리를 완료했음을 나타낸다.
            // 이번 이벤트는 소비되었음을 의미하며, 더 이상 클릭 이벤트가 상위로 전파되지 않는다.
        }
    }
}

할 일 목록 앱 만들기

  • 버튼을 누를 때 마다 addActivity를 호출한다.
  • 데이터가 null일수도 있음을 ?로 표현한다.
  • !!로 널이 들어갈 수 없음을 표현한다.

인텐트로 데이터 전달하기

  • 인텐트를 통해 데이터를 전달할 수 있다.

getString(), getStringExtra()

  • MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.fabMain.setOnClickListener {

            /** 6.1 intent에 Addactivity 객체를 넣는다.
             */
            // 버튼을 클릭하면 인텤트를 시스템에 전달한다.
            // 클래스 타입 레퍼런스 정보를 전달한다.
            val intent = Intent(this, AddActivity::class.java)

            /** 6.2 현재 날짜 변수 생성, putExtra()를 통해 인텐트에 시간을 여는 액티비티에 전달한다.
             */
            // 날짜 전달하기
            val dateFormat = SimpleDateFormat("yyyy-MM-dd") //년 월 일 java를 사용한다.
            intent.putExtra(
                "today",
                dateFormat.format(System.currentTimeMillis())
            ) // 현재 시간을 가져와서 인텐트에 넣어준다.

        }        
}
  • AddActivity
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        var date = intent.getStringExtra("today") // 값을 전달받는다.
 }

ActivityResultLauncher<Intent>

  • addActivity에서 나를 불렀던 곳으로(mainactivity) 돌아가는 경우 값을 전달할 때
    • ActivityResultLauncher를 사용한다.
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        /** 5. 인텐트와 인텐트에서 값을 받아오기 구현
         * registerForActivityResult.. : 다른 액티비티를 시작하고, 그 액티비티가 종료될 때 결과를 받기 위해 사용한다.
         * startActivityForResult를 대체한다.
         * requestLauncher : ActivityResultLauncher를 생성하고 intent를 받아 해당 인텐트를 시작한다. */
        // 결과를 전달받는 인텐트를 호출한다.
        // 결과 처리 함수를 중괄호 안에 작성한다.
        val requestLauncher: ActivityResultLauncher<Intent> =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {//intent 를 전달한다.
                /** 5.1 result 라는 name으로 종료될 때 넘긴 값을 받아온다. */
                it.data!!.getStringExtra("result")?.let {
                    datas?.add(it) // datas가 null이 아니면 it: 받아온 데이터를 datas에 추가한다.
                    adapter.notifyDataSetChanged() // 변화를 반영한다.
                }
            }

        /** 6. floating action button의 리스너 등록
         */
        binding.fabMain.setOnClickListener {

            /** 6.1 intent에 Addactivity 객체를 넣는다.
             */
            // 버튼을 클릭하면 인텐트를 시스템에 전달한다.
            // 클래스 타입 레퍼런스 정보를 전달한다.
            val intent = Intent(this, AddActivity::class.java)

            /** 6.3 앞에서 만들어둔 requestLauncher로 실제 인텐트를 실행한다.
             */
            requestLauncher.launch(intent)

        }
    }
  • AddActivity
        binding.btnSave.setOnClickListener {
            // ActivityLauncher 로 돌아가기
            val intent = intent
            intent.putExtra("result", binding.etAdd.text.toString()) // 사용자 입력을 가져온다.
            setResult(Activity.RESULT_OK, intent) //  requset launcher로 돌아가기

            finish() //finish되어 현재 액티비티를 종료한다. 이전 스택에 쌓여 있던 액티비티가 표시된다.
            true // 클릭 이벤트 핸들러에서 이벤트 처리를 완료했음을 나타낸다.
            // 이번 이벤트는 소비되었음을 의미하며, 더 이상 클릭 이벤트가 상위로 전파되지 않는다.
        }

뒤로가기 구현

  • 부모자식 관계를 설정해준다.
          <activity
            android:name=".AddActivity"
            android:parentActivityName=".MainActivity"
            android:exported="true" />
  • themes.xml에서 NoactionBar를 삭제하여 기본 액션바를 활성화한다.
  • AddActivity
  supportActionBar?.setDisplayHomeAsUpEnabled(true)

리사이클러뷰 저장

  • 화면을 회전한 후에 oncreate가 실행되기 때문에 초기화된다.
        // oncreate가 다시 호출되어도  리사이클러뷰의 내용이 그대로 있게 저장한다.
       override fun onSaveInstanceState(outState: Bundle) {
           super.onSaveInstanceState(outState)
           outState.putStringArrayList("datas", ArrayList(datas))
       }

Intent-filter

  • 제일 처음 실행될 액티비티를 표시할 수 있다.
    기본값 : MainActivity

        <application>
           <activity
               android:name=".AddActivity"
               android:parentActivityName=".MainActivity"
               android:exported="true" />
           <activity
               android:name=".MainActivity"
               android:exported="true">
               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />
    
                   <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
           </activity>
       </application>

Content Provider

  • 안드로이드는 보안상 앱에서 사용하는 데이터를 외부에서 접근할 수 없다.

  • 파일이나 데이터베이스를 외부 앱에서 사용하도록 하려면 콘텐츠 프로바이더를 만들어서 외부로 제공해야 한다.

  • URI : Uniform Resource Identifier

    • Content Provider에서 제공하는 데이터에 접근하기 위한 주소이다.
    • 프로토콜:패키지명/경로/아이디 형식으로 지정한다.
profile
안녕하세요.

0개의 댓글