반응형

Activity

Activity 추가

  • 새 Activity 추가시 AndroidManifest.xml에 Activity 추가 필요
class NewActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}
<activity android:name=".NewActivity" />

Activity 생명주기

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("test", "onCreate() - 액티비티 생성시 호출")
    }

    override fun onStart() {
        super.onStart()
        Log.d("test", "onStart() - 액티비티 실행시 호출")
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("test", "onRestart() - 액티비티 재실행시 호출")
    }

    override fun onPause() {
        super.onPause()
        Log.d("test", "onPause() - 액티비티 안보이면 호출")
    }

    override fun onStop() {
        super.onStop()
        Log.d("test", "onStop() - 액티비티 종료되면 호출")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("test", "onDestroy() - 액티비티 제거되면 호출")
    }
}

참고

startActivity

설명

  • Activity나 Service 등을 실행하기 위해서는 개발자가 직접 실행하는 것이 아닌 OS에 실행을 요청하게 된다.
  • 이 때 실행 요청을 위한 정보를 담는 객체가 Intent이다.
  • 새 Activity가 기존 Activity 위에 띄워질 경우 기존 Activity는 Back Stack에 담겨 정지 상태가 된다.
  • 새 Activity가 Back Stack에 있던 Activitiy가 다시 활동하게 된다.
  • Activity간 객체 전달시 Parcelable 인터페이스를 구현해서 사용해야한다. (동일 객체를 전달하는것이 아닌 새 객체로 복원하는 방식)
  • 주의 : 새 액티비티 추가시 AndroidManifest.xml에 액티비티를 등록해주어야한다.

코드

res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start activity" />

</LinearLayout>
res/layout/activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".SecondActivity">

    <Button
        android:id="@+id/finishButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="finish" />

</LinearLayout>
MyData
class MyData : Parcelable {
    var data1 = 0
    var data2: String? = null

    override fun writeToParcel(dest: Parcel?, flags: Int) {
        dest?.writeInt(data1)
        dest?.writeString(data2)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<MyData> {
        override fun createFromParcel(parcel: Parcel): MyData {
            val myData = MyData()

            myData.data1 = parcel.readInt()
            myData.data2 = parcel.readString()

            return myData
        }

        override fun newArray(size: Int): Array<MyData?> {
            return arrayOfNulls(size)
        }
    }
}
MainActivity
class MainActivity : AppCompatActivity() {
    private val SECOND_ACTIVITY = 1

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = findViewById<Button>(R.id.button)

        button.setOnClickListener {
            val myData = MyData()
            myData.data1 = 100
            myData.data2 = "문자열1"

            val intent = Intent(this, SecondActivity::class.java)

            intent.putExtra("data1", 100)
            intent.putExtra("data2", "Hello World")
            intent.putExtra("myData", myData)

            // startActivity(intent)
            startActivityForResult(intent, SECOND_ACTIVITY)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
            SECOND_ACTIVITY -> {
                val data1 = data?.getIntExtra("data1", 0)
                val data2 = data?.getStringExtra("data2")

                Toast.makeText(this, "SecondActivity 종료 : $resultCode, $data1, $data2", Toast.LENGTH_SHORT).show()
            }
        }
    }
}
SecondActivity
class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        val data1 = intent.getIntExtra("data1", 0)
        val data2 = intent.getStringExtra("data2")
        val myData = intent.getParcelableExtra<MyData>("myData")

        Toast.makeText(this, "data1 : $data1, data2 : $data2, myData.data1 : ${myData?.data1}, myData.data2 : ${myData?.data2}", Toast.LENGTH_SHORT).show()

        val finishButton = findViewById<Button>(R.id.finishButton)

        finishButton.setOnClickListener {
            val finishIntent = Intent()

            finishIntent.putExtra("data1", 100)
            finishIntent.putExtra("data2", "Bye World")

            // setResult(Activity.RESULT_OK)
            setResult(Activity.RESULT_OK, finishIntent)
            finish()
        }
    }
}

참고

onNewIntent

설명

  • intent를 전달 받은 액티비티가 foreground 상태일 경우 onCreate이 아닌 onNewIntent에서 intent 값을 참고할 수 있다.

코드

MainActivity
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("TAG", "onCreate - ${intent.getStringExtra("message")}")
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)

        // MainActivity가 띄워져 있는 상태에서 intent에 데이터를 담아 MainActivity를 다시 띄울 경우 onNewIntent가 호출된다.
        Log.d("TAG", "onNewIntent - ${intent?.getStringExtra("message")}")
    }

    fun onClick(view: View) {
        val intent = Intent(this, MainActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
        intent.putExtra("message", "Hello World")

        startActivity(intent)
    }
}

참고

Intent Filter

설명

  • 다른 애플리케이션이 실행할 수 있도록 하고자 한다면 Intent Filter를 이용해 이름을 설정해주면 된다.

액티비티가 띄워질 앱 코드

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

    <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.ActivityApp1">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SecondActivity">
            <intent-filter>
                <action android:name="com.test.second" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

액티비티를 띄울 앱 코드

MainActivity
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = findViewById<Button>(R.id.button)

        button.setOnClickListener {
            val intent = Intent("com.test.second")
            startActivity(intent)
        }
    }
}

참고

Activity Action

설명

  • 안드로이드에서 제공되는 기본 애플리케이션 중 다른 애플리케이션이 사용할 수 있도록 제공하는 Activity 활용
  • ex) 구글맵, 웹브라우저

코드

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

    <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.Androidexample">
        <activity android:name=".MainActivity">
            <intent-filter>
                <!-- Entry Point -->
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <uses-permission android:name="android.permission.CALL_PHONE" />
</manifest>
MainActivity
class MainActivity : AppCompatActivity() {
    private val permissionList = arrayOf(
        Manifest.permission.CALL_PHONE
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        checkPermission()

        val button = findViewById<Button>(R.id.button)

        button.setOnClickListener {
            /*
            val uri = Uri.parse("geo:37.243243,131.861601")
            val intent = Intent(Intent.ACTION_VIEW, uri)
            startActivity(intent)
            */

            /*
            val uri = Uri.parse("http://developer.android.com")
            val intent = Intent(Intent.ACTION_VIEW, uri)
            startActivity(intent)
            */

            /*
            val uri = Uri.parse("tel:00000000000")
            val intent = Intent(Intent.ACTION_DIAL, uri)
            startActivity(intent)
            */

            val uri = Uri.parse("tel:00000000000")
            val intent = Intent(Intent.ACTION_CALL, uri) // 전화 거는 액션은 권한 등록 필요
            startActivity(intent)
        }
    }

    private fun checkPermission() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return
        }

        for (permission : String in permissionList) {
            val check = checkCallingOrSelfPermission(permission)

            if (check == PackageManager.PERMISSION_DENIED) {
                requestPermissions(permissionList, 0)
            }
        }
    }
}

참고

Activity 회전

설명

  • 화면 회전 발생시 화면을 새롭게 만들게 된다.
  • 이 때 UI 요소들은 초기값으로 설정되기 때문에 복원 처리가 필요할 수 있다.
  • 가로모드, 세로모드에 따라 UI를 다르게 보여줄 수 있다.

코드

res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="click" />

</LinearLayout>
res/layout-land/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/editText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="4" />

        <Button
            android:id="@+id/button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="click" />

    </LinearLayout>
</LinearLayout>
MainActivity
class MainActivity : AppCompatActivity() {
    private var textView: TextView? = null
    private var editText: EditText? = null
    private var button: Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        textView = findViewById(R.id.textView)
        editText = findViewById(R.id.editText)
        button = findViewById(R.id.button)

        button?.setOnClickListener {
            textView?.text = editText?.text
        }

        // 화면 회전 발생 후 textView에 이전 값 설정
        if (savedInstanceState != null) {
            textView?.text = savedInstanceState.getString("data1")
        }
    }

    // 화면 회전 발생 전 아래 메소드 호출
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)

        outState.putString("data1", textView?.text.toString())
    }
}

화면 회전을 막기 위한 코드

manifests/AndroidManifest.xml
<activity android:name=".MainActivity" android:screenOrientation="portrait">
    ...
<activity>

참고

반응형

'Development > Android' 카테고리의 다른 글

[Android] ContextMenu  (0) 2021.02.09
[Android] OptionMenu  (0) 2021.02.09
[Android] RecyclerView  (0) 2021.02.09
[Android] ViewPager  (0) 2021.02.09
[Android] Spinner  (0) 2021.02.09

+ Recent posts