웹_프론트_백엔드/JAVA프레임윅기반_풀스택

2020.04.17

shine94 2020. 4. 17. 09:10

1. 안드로이드 4대 컴포넌트 
1) Activity : 화면을 구성하는 객체


2) Service : 백그라운드에서 동작하는 객체


3) Content Provider : 앱들 간의 데이터를 주고 받기 위해 제공


4) Broadcast Receiver : 주소록에 등록되면 다른 앱들이 수신해서 필요한 정보인 경우 반영 할 수 있게 하는 것

 

 

2. 안드로이드 앱은 코드로 종료시키는 방법은 없다(즉, 액티비티를 끌 수는 있으나 종료 시킬 수 없다는 의미)
   유일하게 앱을 종료시킬 수 있는 방법은 사용자가 직접 밀어서 종료시키는 방법 밖에 없다

 

 

3. 액티비티 생명 주기(Activity Life cycle)란?
 : 액티비티의 상태 전환 과정


** 안드로이드 시스템은 앱 화면 (액티비티)를 관리하는 독특한 시스템 제공

 

** 액티비티가 생성 - 실행 - 중지 - 해제에 이르기까지 전 과정을 관리하며,

    각각의 과정으로 전이될때마다 자동으로 호출되는 메소드를 제공

 

 

4. 액티비티 생명 주기(Activity Life cycle)가 필요한 이유?
 : PC에 비해 낮은 성능 때문에

 

 

5. 액티비티의 상태(state)
1) 실행(Running) 
 : 화면상에 액티비티가 보여지며 실행중인 상태, 사용자가 입력을 받을 수 있는 상태(포커스를 갖고 있다고 함)
   onResume() ~ onPause()


2) 일시정지(Paused)
 : 화면상에 액티비티가 보여지나 사용자 입력을 받을 수 없는 상태(포커스를 받지 못한다고 함)
   onStart() ~ onResume(), onPause() ~ onStop()

 

3) 중지(Stopped)
 : 다른 액티비티에 완전히 가려져 보이지 않는 상태
   onCreate() ~ onStart(), onStop() ~ onDestroy()

 

 

6. Killable state[onPause() ~ onDestroy()]는 언제든지 shut doun 될 수 있다.

   (즉! 순서대로 진행되지 않을 수도 있다는 뜻...!!)

 

 

7. onCreate() : 액티비티가 처음 생성되었을때 호출, 
   onStart() : 화면에 보여지기 시작, 
   onResume() : 사용자 입력받기 시작, 
   onPause() : 다른 액티비티가 전면에 나옴, 
   onStop() : 화면에 안보임, 
   onDestroy() : 액티비티 소멸

 

[안드로이드 실습]

1. a006_widget2

1) Main4Activity 액티비티, activity_main4 레이아웃

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

    <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/AppTheme">

        <activity android:name=".Main4Activity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <activity android:name=".Main3Activity" />
        <activity android:name=".Main2Activity" />
        <activity android:name=".MainActivity" />
    </application>

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

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="RatingBar"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1" />

    <RatingBar
        android:id="@+id/ratingBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:numStars="4"
        android:rating="2.5"
        android:stepSize="0.5"
        android:isIndicator="false" />
    <!-- isIndicator 가 false 이어야 사용자 조작 가능 (디폴트) -->
    <!-- rating : 초기 값 -->

    <TextView
        android:id="@+id/tvResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="결과값"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

</LinearLayout>
package com.lec.android.a006_widget2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.RatingBar;
import android.widget.TextView;

public class Main4Activity extends AppCompatActivity {

    RatingBar rb;
    TextView tvResult;

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

        rb = findViewById(R.id.ratingBar);
        tvResult = findViewById(R.id.tvResult);

        // RatingBar 의 값이 변할 때 호출되는 콜백
        rb.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
                tvResult.setText("rating : " + rating);
            }
        });

    } // end onCreate()

} // and Activity

 

 

2. a007_activity 모듈

1) MainActivity 액티비티, activity_main 레이아웃

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

    <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/AppTheme">
        
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

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

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Activity LifeCycle"
        android:textAppearance="@style/TextAppearance.AppCompat.Display2" />

    <EditText
        android:id="@+id/et1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="number"
        android:text="100" />

    <EditText
        android:id="@+id/et2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="number"
        android:text="33" />

    <TextView
        android:id="@+id/tvResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="결과창"
        android:textAppearance="@style/TextAppearance.AppCompat.Display2" />

    <Button
        android:id="@+id/btnAction"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />
</LinearLayout>
package com.lec.android.a007_activity;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.PersistableBundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

/**
 * 액티비티 (Activity) :
 *      안드로이드의 4대 컴포넌트중 하나인 '화면' UI 객체
 *      앱에서 사용하는 액티비티는 반.드.시 메니페스트 에 등록되어야 함.
 *
 * 액티비티의 라이프 사이클
 *      onCreate() : 액티비티가 생성될때 호출, 사용자 인터페이스 초기화에 사용
 *          onStart() : 액티비티가 사용자에게 보여지기 바로 직전에 호출됨
 *              onResume() : 액티비티가 동작, 즉 사용자와 상호작용. (포커스를 갖기시작) 할때 호출
 *              onPause() : 다른 액티비티가 보여질때 (혹은 다른 액티비티에 의해 가려지기 시작할때) 호출됨
 *          onStop() : 액티비티가 더이상 안보여질때 호출되는 메소드.
 *      onDestory() : 액티비티 소멸될때 호출.
 *      onRestart() : onStop -> onStart 전환될때 호출됨.
 *
 *      [공식] : CTRL+클릭 !
 *      https://developer.android.com/guide/components/activities/activity-lifecycle
 *      https://developer.android.com/reference/android/app/Activity
 *
 *
 * 액티비티의 상태정보(state) 저장및 복원
 *      onRestoreInstanceState() :  onStart 직후에 호출됨.
 *      onSaveInstanceState() : 액티비티 소멸전에 호출된다.
 *
 *  ※ AVD/안드로이드폰 테스트시:  '화면 회전' 옵션을 켜주세요.
 */

public class MainActivity extends AppCompatActivity {

    EditText et1, et2;
    TextView tvResult;
    Button btnAction;

    // 액티비티가 생성될때 호출
    // 주로 사용자 인터페이스 초기화에 사용
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.d("myapp","onCreate");

        et1 = findViewById(R.id.et1);
        et2 = findViewById(R.id.et2);
        tvResult = findViewById(R.id.tvResult);
        btnAction = findViewById(R.id.btnAction);

        btnAction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int a = Integer.parseInt(et1.getText().toString().trim());
                int b = Integer.parseInt(et2.getText().toString().trim());
                tvResult.setText("" + (a + b));
            }
        });

    } // end onCreate()

    // 액티비티가 사용자에게 보여지기 시작할때(바로 직전)에 호출
    @Override
    protected void onStart() {
        super.onStart();
        Log.d("myapp", "onStart");
    }

    // 액티비티가 동작, 즉 사용자와의 상호작용(포커스를 갖기 시작)할때 호출
    @Override
    protected void onResume() {
        super.onResume();
        Log.d("myapp", "onResume");
    }

    // 다른 액티비티가 보여질때 (혹은 다른 액티비티에 의해 가려지기 시작할때) 호출
    // 액티비티를 통해 다루고 있던 데이터 저장, 쓰레드 중지 ... 등의 처리를 해야 함.
    @Override
    protected void onPause() {
        super.onPause();
        Log.d("myapp", "onPause");
    }

    // 액티비티가 더이상 안보여질때 호출되는 메소드
    // 메모리 상황에 따라 호출 안될 수도 있음
    @Override
    protected void onStop() {
        super.onStop();
        Log.d("myapp", "onStop");
    }

    // 액티비티 소멸될때 호출
    // 액티비티 소멸은
    //  시스템에 의해서 소멸되기도 하고
    //  코드를 통해 제거되기도 함 : 예) finish()
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("myapp", "onDestroy");
    }

    // onStop -> onStart 전환될때 호출
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("myapp", "onRestart");
    }

    // 직전에 저장되어 있던 액티비티의 상태정보가 있다면,
    // onRestoreInstanceState() 는 onStart 직전에 호출됨
    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d("myapp", "onRestoreInstanceState");

        if(savedInstanceState != null) {
            tvResult.setText(savedInstanceState.getString("value"));
        }
    }


    // 액티비티 소멸 전에 호출된다. (주의! onPause 뒤에 호출된다고 간주하지 말것!)
    // outState : <-- 액티비티 정보 저장(백업)하여 나중에 onCreate 에서 사용가능
    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d("myapp", "onSaveInstanceState");

        outState.putString("value", tvResult.getText().toString());
    }

} // end Activity

 

** 앱 실행 

** 앱 일시정지

** 앱 다시 실행

** 앱 중지

** 앱 다시 실행

** 회전하면서 결과 값을 잃었다..!!

** 아래의 코드를 추가하면 회전해도 값을 저장할 수 있다..!!

** 이젠 회전해도 값을 잃지 않는다..!!

2) Main2Activity, MyTwo 액티비티, activity_main2, activity_my_two 레이아웃, Persion 클래스

** manifest

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

    <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/AppTheme">
        
        <activity android:name=".MyTwo" />
        <activity android:name=".Main2Activity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

** activity_main2 레이아웃

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

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Intent(인텐트)"
        android:textAppearance="@style/TextAppearance.AppCompat.Display3" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이름과 나이 입력"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="이름을 입력하세요"
        android:inputType="textPersonName"
        android:text="슈퍼맨" />

    <EditText
        android:id="@+id/etAge"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="나이를 입력하세요"
        android:inputType="number"
        android:text="10" />

    <Button
        android:id="@+id/btnStartTwo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="화면전환 startActivity()"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <!-- Button 은 기본적으로 대문자로 표시된다
        textAllCaps 를 사용하면 이 기본 동작을 바꿀수 있다.-->
    <Button
        android:id="@+id/btnFinish"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        android:text="액티비티 종료 finish()" />
</LinearLayout>

** activity_my_two 레이아웃

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFEB3B"
    android:orientation="vertical"
    tools:context=".MyTwo">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="두번째 화면"
        android:textAppearance="@style/TextAppearance.AppCompat.Display2" />

    <Button
        android:id="@+id/btnFinish"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="액티비티 종료 finish()"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="match_parent"
        android:layout_height="75dp"
        android:text="인텐트로 받은값"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="match_parent"
        android:layout_height="97dp"
        android:text="인텐트로 받은값"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <Button
        android:id="@+id/btnToMain"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="메인액티비티 startActivity()"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</LinearLayout>

** Main2Activity 액티비티

package com.lec.android.a007_activity;

import androidx.appcompat.app.AppCompatActivity;

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

/**
 * 화면(액티비티)전환 - 인텐트 사용 (인텐트 날린다?)
 *  1. 다음에 넘어갈 액티비티 준비
 *  2. 메니페스트에 액티비티 등록
 *  3. Intent 객체 만들어서 startActivity() 한다
 *      - Intent 로 데이터 주고 받기 :  putExtra() -> getXXXExtra()
 *      - 주고받은 Object 는 Serializable 되어 있어야 한다
 *
 *  안드로이드는 startActivity() 로 새 액티비티를 시작하면
 *  적측형(stack) 구조로 액티비티가 운영된다.
 */

public class Main2Activity extends AppCompatActivity {

    EditText etName;
    EditText etAge;

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

        etName = findViewById(R.id.etName);
        etAge = findViewById(R.id.etAge);

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

        btnStartTwo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(
                        getApplicationContext(),    // 현재 화면의 제어권자
                        MyTwo.class                 // 다음 화면의 액티비티 클래스 지정
                );

                // 데이터를 Intent 에 실어서 보내기
                // name : 데이터 형태로 보냄
                intent.putExtra("num", 3);
                intent.putExtra("num2", 7);
                intent.putExtra("long", 33L);
                intent.putExtra("msg", "안녕하세요");

                // 이름, 나이 --> Person 에 담은뒤 Intent 에 실어 보내기
                Person p = new Person(
                        etName.getText().toString(),
                        Integer.parseInt(etAge.getText().toString())
                );

                intent.putExtra("Person", p);

                startActivity(intent);  // 다음 화면으로 넘어간다.

            }
        });

        Button btnFinish = findViewById(R.id.btnFinish);
        btnFinish.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();   // 액티비티 종료
            }
        });

    } // end onCreate()

}// and Activity

** MyTwo 액티비티

package com.lec.android.a007_activity;

import androidx.appcompat.app.AppCompatActivity;

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

public class MyTwo extends AppCompatActivity {

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

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

        btnFinish.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();   // 액티비티 종료
            }
        });

        // 넘겨받은 Intent 객체를 받는다
        Intent intent = getIntent();

        int a = intent.getIntExtra("num", 0);   // "num" 이라는 name 으로 넘어온 값
                                            // 만약 "num" 이라는 name 이 인텐트에 없었으면
                                            // 디폴트값 (두번째 매개변수)를 리턴

        int b = intent.getIntExtra("num2", 0);
        int c = intent.getIntExtra("num3", 999);    // "num3" 라는 이름은 없었다!
        long l = intent.getLongExtra("long", 0);

        String msg = intent.getStringExtra("msg");  // 리턴값이 Object 인 경우, 디폴트값 설정 없다.
                                            // name 이 없으면 null 리턴

        TextView tv1 = findViewById(R.id.tv1);
        tv1.setText("인텐트 받은 값 : " + a + " : " + b + " : " + c + " : " + l + " : " + msg);

        // Person 데이터 받기
        Person p = (Person)intent.getSerializableExtra("Person");

        TextView tv2 = findViewById(R.id.tv2);
        tv2.setText("Person 받은 값 : " + p.getName() + " : " + p.getAge());


        // 첫번째 액티비티로 인텐트를 날리면??
        Button btnToMain = findViewById(R.id.btnToMain);
        btnToMain.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
                startActivity(intent);
            }
        });

    } // end onCreate()

} // end activity

** Person 클래스

package com.lec.android.a007_activity;

import java.io.Serializable;

// Intent 에 담아 보내는 객체는 반.드.시 serializable 되어 있어야 한다.
public class Person implements Serializable {
    String name;
    int age;

    // AndroidStudio 에서 Alt + Insert 로 자동 생성!
    
    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }
}

 

3) Main3Activity, CalcActivity 액티비티, activity_main3 레이아웃

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

    <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/AppTheme">

        <activity android:name=".CalcActivity"></activity>
        <activity android:name=".Main3Activity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <activity android:name=".MyTwo" />
        <activity android:name=".Main2Activity" />
        <activity android:name=".MainActivity" />
    </application>

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

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Intent 값 돌려받기"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1" />

    <EditText
        android:id="@+id/et1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="number"
        android:text="100" />

    <EditText
        android:id="@+id/et2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="number"
        android:text="200" />

    <Button
        android:id="@+id/btnStart"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="startForResult()"
        android:textAllCaps="false"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/tvResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="결과값"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />


</LinearLayout>

** Main3Activity 액티비티

package com.lec.android.a007_activity;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

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

public class Main3Activity extends AppCompatActivity {

    EditText et1, et2;
    Button btnStart;
    TextView tvResult;

    private final int REQUEST_CODE_CALC = 101;

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

        et1 = findViewById(R.id.et1);
        et2 = findViewById(R.id.et2);
        btnStart = findViewById(R.id.btnStart);
        tvResult = findViewById(R.id.tvResult);

        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int a = Integer.parseInt(et1.getText().toString());
                int b = Integer.parseInt(et2.getText().toString());

                Intent intent = new Intent(getApplicationContext(), CalcActivity.class);
                intent.putExtra("num1", a);
                intent.putExtra("num2", b);

                // 일반적인 화면전환
                //startActivity(intent);

                // 값을 돌려받기 위한 화면전환
                startActivityForResult(intent, REQUEST_CODE_CALC);
            }
        });

    } // end onCreate()

    // startActivityForResult()로 넘어갔던 화면으로부터 결과값을 돌려받으면 호출되는 메소드
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode == RESULT_OK) {   // 정상 반환인 경우

            switch (requestCode) {
                case REQUEST_CODE_CALC:
                    int a = data.getIntExtra("plus", 0);
                    int b = data.getIntExtra("minus", 0);

                    tvResult.setText(requestCode + "] 받아온 값: " + a + " : " + b);
                    break;
            }

        } else {
            // 정상 결과가 아닌 경우 처리

        }
    }
} // and Activity

** CalcActivity 액티비티

package com.lec.android.a007_activity;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;

// 화면이 없는 액티비티 생성 가능
public class CalcActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        int num1 = intent.getIntExtra("num1", 0);
        int num2 = intent.getIntExtra("num2", 0);

        intent.putExtra("plus", num1 + num2);
        intent.putExtra("minus", num1 - num2);

        // 호출한 화면에 값 되돌려 주기
        setResult(RESULT_OK, intent);

        finish();   // onDestroy() 와 동일


    } // end onCreate()

} // end Activity

 

 

3. a008_recycler 모듈

1) MainActivity, PhonebookDetail 액티비티, activity_main, item, activity_phonebook_detail 레이아웃,

   Phonebook, PhonebookAdapter, D 클래스

** 필요한 사진 다운 받기 : res > drawable 폴더에 Ctrl + V

** RecyclerView는 Add Project Dependency를 해야 사용할 수 있음

** Dependency가 필요한 경우 그림과 같이 화살표 모양을 볼 수 있음
 : 화살표 모양 클릭 > Project Dependency를 추가할 것인지 물어보는 팝업창 뜸 > OK 클릭 > 다운로드 완..!!

[중요] Project Dependency가 정상적으로 추가되면 아래의 gradle 파일에서 
        implementation 'androidx.recyclerview:recyclerview:1.0.0' 가 추가됨

** CardView도 Add Project Dependency를 해야 사용할 수 있음
** Dependency가 필요한 경우 그림과 같이 화살표 모양을 볼 수 있음

 : 화살표 모양 클릭 > Project Dependency를 추가할 것인지 물어보는 팝업창 뜸 > OK 클릭 > 다운로드 완..!!

[중요] Project Dependency가 정상적으로 추가되면 아래의 gradle 파일에서  

        implementation 'androidx.cardview:cardview:1.0.0' 가 추가됨

** manifest

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

    <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/AppTheme">
        
        <activity android:name=".PhonebookDetail"></activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

 

** activity_main 레이아웃

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

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Phonebook"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1" />


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

        <Button
            android:id="@+id/btnInsert"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="INSERT" />

        <Button
            android:id="@+id/btnAppend"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="APPEND" />
    </LinearLayout>


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

** item 레이아웃 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <!--
    CardView 의 atrrribute 속성은 위의 app 네임스페이스를 사용하게 됩니다.
        cardCornerRadius : 코너 둥글게 하기
        cardElevation : 바닥에서 떨어져 보이게 하기
        cardUseCompatPadding : CardView 내용에 따라 그림자 보여줄지 결정. API21 이상에서도 호환되게 padding 사용
    -->
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="183dp"
        app:cardBackgroundColor="#FFFFFFFF"
        app:cardCornerRadius="10dp"
        app:cardElevation="5dp"
        app:cardUseCompatPadding="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/ivPhoto"
                android:layout_width="103dp"
                android:layout_height="105dp"
                android:layout_marginStart="16dp"
                android:layout_marginTop="16dp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@mipmap/ic_launcher" />

            <TextView
                android:id="@+id/tvName"
                android:layout_width="184dp"
                android:layout_height="37dp"
                android:layout_marginStart="20dp"
                android:layout_marginTop="16dp"
                android:text="name"
                android:textSize="30sp"
                app:layout_constraintStart_toEndOf="@+id/ivPhoto"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/tvPhone"
                android:layout_width="214dp"
                android:layout_height="24dp"
                android:layout_marginStart="20dp"
                android:layout_marginTop="12dp"
                android:text="phone"
                android:textSize="18sp"
                app:layout_constraintStart_toEndOf="@+id/ivPhoto"
                app:layout_constraintTop_toBottomOf="@+id/tvName" />

            <TextView
                android:id="@+id/tvEmail"
                android:layout_width="214dp"
                android:layout_height="17dp"
                android:layout_marginStart="20dp"
                android:layout_marginTop="12dp"
                android:text="email"
                app:layout_constraintStart_toEndOf="@+id/ivPhoto"
                app:layout_constraintTop_toBottomOf="@+id/tvPhone" />

            <Switch
                android:id="@+id/swOnOff"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="16dp"
                android:layout_marginBottom="12dp"
                android:text="On/Off"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent" />

            <ImageButton
                android:id="@+id/btnDelItem"
                android:layout_width="37dp"
                android:layout_height="39dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="12dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@android:drawable/ic_delete" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.cardview.widget.CardView>
</LinearLayout>

** activity_phonebook_detail 레이아웃 

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

    <ImageView
        android:id="@+id/ivPhoto"
        android:layout_width="match_parent"
        android:layout_height="125dp"
        app:srcCompat="@android:drawable/btn_dialog" />

    <TextView
        android:id="@+id/tvName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1" />

    <TextView
        android:id="@+id/tvPhone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/tvEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <Button
        android:id="@+id/btnBack"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="돌아가기" />
</LinearLayout>


** MainActivity 액티비티 

package com.lec.android.a008_recycler;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    PhonebookAdapter adapter;  // Adapter 객체
    RecyclerView rv;

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

        rv = findViewById(R.id.rv);

        // RecyclerView 를 사용하기 위해서는 LayoutManager 지정해주어야 한다.
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        //RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this, 2);

        rv.setLayoutManager(layoutManager);

        // Adapter객체 생성
        adapter = new PhonebookAdapter();

        initAdapter(adapter);

        rv.setAdapter(adapter);   // RecyclerView 에 Adapter 장착!

        Button btnInsert = findViewById(R.id.btnInsert);
        Button btnAppend = findViewById(R.id.btnAppend);

        btnInsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                insertData(v);
            }
        });

        btnAppend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                appendData(v);
            }
        });


    } // end onCreate()

    // 샘플데이터 가져오기
    protected void initAdapter(PhonebookAdapter adapter){
        // 몇개만 생성
        for(int i = 0; i < 10; i++){
            int idx = D.next();
            adapter.addItem(new Phonebook(D.FACEID[idx], D.NAME[idx], D.PHONE[idx], D.EMAIL[idx]));
        }
    }


    protected void insertData(View v){
        int idx = D.next();

        // 리스트 맨 앞에 추가
        adapter.addItem(0, new Phonebook(D.FACEID[idx], D.NAME[idx], D.PHONE[idx], D.EMAIL[idx]));
        adapter.notifyDataSetChanged();  // 데이터변경을 Adapter 에 알리고, 리스트뷰에 반영 .
    }

    protected void appendData(View v){
        int idx = D.next();

        // 리스트 맨 뒤에 추가
        adapter.addItem(new Phonebook(D.FACEID[idx], D.NAME[idx], D.PHONE[idx], D.EMAIL[idx]));
        adapter.notifyDataSetChanged();  // 데이터변경을 Adapter 에 알리고, 리스트뷰에 반영 .
    }


} // end Activity

 

[추가] LinearLayoutManager.HORIZONTAL로 설정

[추가] LinearLayoutManager.VERTICAL로 설정

[추가] GridLayoutManager로 설정

** PhonebookDetail 액티비티

package com.lec.android.a008_recycler;

import androidx.appcompat.app.AppCompatActivity;

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

public class PhonebookDetail extends AppCompatActivity {

    ImageView ivPhoto;
    TextView tvName, tvPhone, tvEmail;

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

        ivPhoto = findViewById(R.id.ivPhoto);
        tvName = findViewById(R.id.tvName);
        tvEmail = findViewById(R.id.tvEmail);
        tvPhone = findViewById(R.id.tvPhone);

        Intent intent = getIntent();
        Phonebook pb = (Phonebook)intent.getSerializableExtra("pb");
        ivPhoto.setImageResource(pb.getPhoto());
        tvName.setText(pb.getName());
        tvEmail.setText(pb.getEmail());
        tvPhone.setText(pb.getPhone());

        Button btnBack = findViewById(R.id.btnBack);
        btnBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 리스트로 돌아가기
                finish();
            }
        });
        
    } // end onCreate()
    
} // end Activity


** Phonebook 클래스 

package com.lec.android.a008_recycler;

import java.io.Serializable;

// 전화번호부 데이터를 담을 클래스
public class Phonebook implements Serializable {
    int photo; // 사진
    String name; // 이름
    String phone; // 전화번호
    String email; // 이메일

    public Phonebook() {
    }

    public Phonebook(int photo, String name, String phone, String email) {
        this.photo = photo;
        this.name = name;
        this.phone = phone;
        this.email = email;
    }

    public int getPhoto() {
        return photo;
    }

    public void setPhoto(int photo) {
        this.photo = photo;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
} // end Phonebook

** PhonebookAdapter 클래스 

package com.lec.android.a008_recycler;

import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

// Adapter 객체 정의
// 데이터(Phonebook) 을 받아서, 각 item 별로 View 를 생성
public class PhonebookAdapter extends RecyclerView.Adapter<PhonebookAdapter.ViewHolder> {
    // Adapter는 리스트에서 다룰 데이터가 필요하다
    // Adapter가 데이터에 연결되어야 하는 것은 사실이나, 데이터를 Adapter를 직접 다룰지
    // 아니면 별도의 데이터 관리는 따로 하는 구조로 만들지는 선택의 몫
    // 본 예제에서는 Adapter 안에 직접 데이터를 다루어보겠습니다
    List<Phonebook> items = new ArrayList<Phonebook>();

    static PhonebookAdapter adapter;

    // Adapter 생성자
    public PhonebookAdapter() {this.adapter = this;}

    // onCreateViewHolder() : ViewHolder 가 생성될때 호출됨
    // 각 item 을 위해 정의한 레이아웃(ex:XML) 으로 View 객체를 만들어 줍니다.
    // 이들 View객체를 새로 만들 ViewHolder 에 담아 리턴.
    //
    //  'View  타입' 을 위한 정수값이 매개변수로 넘겨진 --> viewType
    //    이를 통해 아이템별로 View를 다양하게 표현 가능.  (ListView 에는 없던 개선점)
    //    예를들면, 각각의 'View 타입' 별로 따로따로 XML레이아웃을 달리 하여 보여줄수 있는 겁니다.
    //    * 그러나, 일반적으로는 한가지만 운용함.*
    //
    //  매개변수로 전달된 ViewGroup 객체는 각 아이템을 위한 객체
    //  이로부터 Context 객체를 뽑아내어 Layout inflation 을 해야 한다.
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        // 주어진 ViewGroup 으로부터 LayoutInflater 추출
        LayoutInflater inf = LayoutInflater.from(parent.getContext());
        // 준비된 레이아웃(XML) 으로부터 View 를 만들어 ViewGroup 에 붙이고
        // 그렇게 만들어진 View 를 리턴한다
        View itemView = inf.inflate(R.layout.item, parent, false);

        // 위에서 마들어진 새로운 View 를 ViewHolder 에 담아 리턴
        return new ViewHolder(itemView);
    }

    // onBindViewHolder() : ViewHolder 가 '재사용' 될때 호출됨
    // View 객체는 그대로 기존것을 사용 (이것이 재사용!) 하고 데이터만 바꾸어 주면 됨.
    //  이전에 이미 만들어진. 재활용할수 있는 ViewHolder 객체  와
    //  리스트 상에 몇번째 데이터인지에 대한 정보 (position) 가 넘어온다
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Phonebook item = items.get(position); // List<> 의 get()
        holder.setItem(item);
    }

    // getItemCount() : 어댑터에서 다루는 현시점 아이템(데이터)의 개수
    //   Selection Widget 에서 수시로 getItemCount() 를 호출하여 뷰를 업데이트 한다
    @Override
    public int getItemCount() {
        return items.size();  // List<> 의 size()
    }


    // nested class (static inner) 로 ViewHolder 클래스 정의
    static class ViewHolder extends RecyclerView.ViewHolder{

        // ViewHolder 에 담긴 각각의 View 들을 담을 변수
        ImageView ivPhoto;
        TextView tvName, tvPhone, tvEmail;
        ImageButton btnDelItem;
        Switch swOnOff;

        // 생성자 필수
        public ViewHolder(@NonNull View itemView) {  // item 레이아웃의 View 객체가 전달됨.
            super(itemView);

            // View 객체 가져오기
            ivPhoto = itemView.findViewById(R.id.ivPhoto);
            tvName = itemView.findViewById(R.id.tvName);
            tvPhone = itemView.findViewById(R.id.tvPhone);
            tvEmail = itemView.findViewById(R.id.tvEmail);

            btnDelItem = itemView.findViewById(R.id.btnDelItem);
            swOnOff = itemView.findViewById(R.id.swOnOff);

            // switch 누르면 전화번호, 이메일 숨기기/보이기
            swOnOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                    if(isChecked){
                        tvPhone.setVisibility(View.INVISIBLE);
                        tvEmail.setVisibility(View.INVISIBLE);
                    } else {
                        tvPhone.setVisibility(View.VISIBLE);
                        tvEmail.setVisibility(View.VISIBLE);
                    }
                }
            });

            // 삭제버튼 누르면 item 삭제되게 하기
            btnDelItem.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // position 정보 필요하다?
                    // adapter 로 부터 데이터 삭제도 진행되어야 한다.
                    adapter.removeItem(getAdapterPosition());  // 데이터 삭제
                    // 데이터 변경 (수정, 삭제, 추가) 내역이 adapter 에 반영되어야 정상적으로 동작함!!! ★★★
                    adapter.notifyDataSetChanged();
                }
            });

            // 클릭리스너 장착
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition();   // 이 리스너가 장착된 item 의 리스트상의 position 값
                    //Toast.makeText(v.getContext(), "position:" + position, Toast.LENGTH_LONG).show();

                    // 아이템을 클릭하면 해당 세부 정보 액티비티로 넘겨주기
                    Intent intent = new Intent(v.getContext(), PhonebookDetail.class);

                    intent.putExtra("pb", adapter.getItem(position));

                    v.getContext().startActivity(intent);
                }
            });



        } // end 생성자

        // Phonebook 데이터를 받아서 멤버변수 세팅
        public void setItem(Phonebook item){
            ivPhoto.setImageResource(item.getPhoto());
            tvName.setText(item.getName());
            tvPhone.setText(item.getPhone());
            tvEmail.setText(item.getEmail());
        }


    }  // end ViewHolder


    // 데이터를 다루기 위한 메소드들
    // ArrayList 의 메소드들 사용
    public void addItem(Phonebook item) {  items.add(item); }
    public void addItem(int position, Phonebook item) {   items.add(position, item);}
    public void setItems(ArrayList<Phonebook> items) {   this.items = items;}
    public Phonebook getItem(int position) {   return items.get(position);}
    public void setItem(int position, Phonebook item) {   items.set(position, item); }
    public void removeItem(int position){ items.remove(position); }


} // end Adapter

** D 클래스

package com.lec.android.a008_recycler;

// 샘플 데이터
public class D {
    public static int [] FACEID = {
            R.drawable.face01,
            R.drawable.face02,
            R.drawable.face03,
            R.drawable.face04,
            R.drawable.face05,
            R.drawable.face06,
            R.drawable.face07,
            R.drawable.face08,
            R.drawable.face09,
            R.drawable.face10,
            R.drawable.face11,
            R.drawable.face12,
            R.drawable.face13,
            R.drawable.face14,
            R.drawable.face15,
            R.drawable.face16,
            R.drawable.face17,
            R.drawable.face18,
            R.drawable.face19,
            R.drawable.face20,
            R.drawable.face21
    };

    public static final String [] NAME = {
            "아이언맨", "캡틴아메리카", "헐크", "블랙위도우", "팔콘", "울트론",
            "로키", "토르", "그루트", "스타로드", "비젼", "앤트맨", "윈터솔져",
            "로난", "토끼", "스파이더맨", "호크아이", "워머신", "가모라", "베놈",
            "디스트로이어"
    };

    public static final String [] PHONE = {
            "001-1111-1111",
            "002-1111-1111",
            "003-1111-1111",
            "004-1111-1111",
            "005-1111-1111",
            "006-1111-1111",
            "007-1111-1111",
            "008-1111-1111",
            "009-1111-1111",
            "010-1111-1111",
            "011-1111-1111",
            "012-1111-1111",
            "013-1111-1111",
            "014-1111-1111",
            "015-1111-1111",
            "016-1111-1111",
            "017-1111-1111",
            "018-1111-1111",
            "019-1111-1111",
            "020-1111-1111",
            "021-1111-1111"
    };

    public static final String [] EMAIL = {
            "001@mail.com",
            "002@mail.com",
            "003@mail.com",
            "004@mail.com",
            "005@mail.com",
            "006@mail.com",
            "007@mail.com",
            "008@mail.com",
            "009@mail.com",
            "010@mail.com",
            "011@mail.com",
            "012@mail.com",
            "013@mail.com",
            "014@mail.com",
            "015@mail.com",
            "016@mail.com",
            "017@mail.com",
            "018@mail.com",
            "019@mail.com",
            "020@mail.com",
            "021@mail.com"
    };

    private static int idx = 0;

    public static int next(){
        idx = idx % FACEID.length;
        return idx++;   // idx 값 리턴하고 1증가
    }

} // end D

'웹_프론트_백엔드 > JAVA프레임윅기반_풀스택' 카테고리의 다른 글

2020.04.21  (0) 2020.04.21
2020.04.20  (0) 2020.04.20
2020.04.16  (0) 2020.04.16
2020.04.14  (0) 2020.04.14
2020.04.13  (0) 2020.04.13