Mediation 개발 가이드 (Android)

1. ADLIB Mediation(수익최적화) 개요

실제 프로젝트 환경에 SDK 적용을 위한 문서입니다.
애드립을 통해 실제 사용할 플랫폼은 프로젝트에서 선택적으로 포함하여 최종 바이너리 크기를 줄일 수 있습니다.
실제 샘플 프로젝트를 컴파일하기 위하여 각 플랫폼 (AD Network) 사이트에서 발급받은
APP-ID 및 각 OS에 맞는 최신 SDK가 별도로 필요합니다.

기본적으로 샘플 프로젝트는 각 플랫폼의 jar 파일만 새로 링크하면 동작하도록 제작 되었으며
실제 플랫폼의 SDK 작동방식이 변하지 않는 한 test.adlib.project.ads 안의 내용을 수정할 필요는 없습니다.
(실제 발급받은 광고 플랫폼 ID 적용 부분은 수정해야 합니다.)

2. 프로젝트 준비

  • test.adlib.project 패키지는 테스트를 위한 Activity가 위치하며 test.adlib.project.ads 패키지는 각 광고플랫폼의 실제 구현부입니다.
  • test.adlib.project.ads 안에서 jar 파일과 마찬가지로 실제 사용할 클래스만 선택하여 최종 파일 크기를 줄일 수 있습니다.



»1) 빌드설정

  • 애드립에서 제공하는 샘플 프로젝트는 Gradle 환경의 안드로이드 스튜디오에서 빌드하기에 최적화되어 있습니다.
			[build.gradle]
			  android {
			        
			        defaultConfig {
			              …
			              multiDexEnabled true 
			        }
			        
			        dexOptions {
			              jumboMode = true              
			          javaMaxHeapSize "4g" 
			        }
			}
			
  • com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 에러가 발생하는 경우 defaultConfig의 multiDexEnable 상태를 꼭 확인해주시기 바랍니다.
  • dexOptions은 빌드 시 OutOfMemoryError가 발생할 경우, 확인해주시기 바랍니다.
  • 안정적인 빌드를 위해 가능하면 프로가드를 사용하도록 권장합니다.

2) 라이브러리 추가

프로젝트 구성

프로젝트 내 [build.gradle] 스크립트

			 dependencies {
			  compile fileTree(dir: 'libs', include: ['*.jar'])
			  compile 'com.google.android.gms:play-services-base:8.4.0'
			  compile 'com.google.android.gms:play-services-ads:8.4.0'
			  compile 'com.android.support:multidex:1.0.0'
			}
			

광고 설정을 위해 설정을 위해 gradle 파일의 dependencies를 추가합니다.

스케쥴에 사용할 AD Network SDK가 ‘libs’ 폴더에 jar형태로 포함해주시기 바랍니다.

  • compile 'com.google.android.gms:play-services-base:8.4.0'
    compile 'com.google.android.gms:play-services-ads:8.4.0'

    안드로이드에서 광고 설정에 필요한 설정입니다. 애드립의 필수는 아니며, 미디에이션을 사용한다면 각 플랫폼 가이드에 따라 추가해주시기 바랍니다.
  • compile 'com.android.support:multidex:1.0.0' : 사용하는 라이브러리가 많아 해당 에러가 발생한다면, 추가해주시기 바랍니다.

3-1) AndroidManifest.xml

  • 아래의 권한을 추가하지 않을 경우 Exception이 발생합니다.
  • 애드립 SDK 최소 버전은 9 입니다.(Android2.3이상)
  • 타플랫폼의 최소버전이 애드립 보다 높다면 변경하시기 바랍니다.
 <uses-sdk android:minSdkVersion=“11” />

 <!-- 애드립 실행에 필요한 권한 -->
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.GET_PACKEAGE_SIZE" />
 <!-- 여기까지 애드립 사용을 위한 필수 권한 -->

 <!-- 플랫폼에 따라 아래의 권한을 추가하시기 바랍니다. (애드립의 필수는 아닙니다.) -->
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
			

3-2) AndroidManifest.xml

프로젝트를 열어 아래와 같이 속성을 확인합니다.

<application
        android:icon="@drawable/icon"
        android:label="@string/app_name" >

<!-- 애드립 사용을 위해 꼭 추가해주세요. -->
<activity
        android:name="com.mocoplex.adlib.AdlibDialogActivity"
        android:theme="@android:style/Theme.Translucent"
        android:configChanges="orientation|screenSize|keyboard|keyboardHidden" />
</application>
			

3-3) AndroidManifest.xml

Android 9에서 보안 개선을 위해 TLS 네트워크를 기본으로 합니다.
Android 9이상을 대상으로 하는 경우 usesCleartextTraffic 을 true로 설정 해 주셔야 HTTP 통신이 가능합니다.
(Adlib은 기본적으로 HTTP 통신을 사용합니다.)

<application
        ...
        android:usesCleartextTraffic="true"
        ... >
</application>
			

3. 프로젝트 연동

3-1. ADLIB Key 설정

애드립 광고를 적용하기 위해선 https://mkt.adlibr.com/adn/dashboard.jsp 에서 에서 ADLIB API KEY를 각 애드립을 사용하는 액티비티에 필수로 넣어주어야 합니다.

샘플 프로젝트의 AdlibTestProjectConstans.java 클래스의 설정과 같이 ADLIB API KEY를 설정해주고 ADLIB TEST MODE를 설정할 수 있습니다.


public class AdlibTestProjectConstans {
// 애드립 광고를 테스트 하기 위한 키 입니다. 
public static String ADLIB_API_KEY = "ADLIB API KEY를 입력해주세요."; 

// false : 상용 광고, true : 테스트 광고 
public static boolean ADLIB_TEST_MODE = false;
}
		

»AdlibActivity를 상속하는 Activity

AdlibActivity를 상속하는 경우, setAdlibKey 메서드를 통해 패키지 별 키를 설정합니다.
자세한 구현 방법은 샘플 프로젝트의 각 액티비티를 참고해주세요.

// 각 애드립 액티비티에 애드립 앱 키값을 필수로 넣어주어야 합니다.
setAdlibKey(AdlibTestProjectConstans.ADLIB_API_KEY);

// 테스트 광고 노출
setAdlibTestMode(AdlibTestProjectConstans.ADLIB_TEST_MODE);
			 

»일반 Activity를 상속하는 Activity

일반 Activity를 상속하는 경우, AdlibManger를 선언하여 Adlib Key를 설정합니다.
자세한 구현 방법은 샘플 프로젝트의 AdlibTestProjectActivty4.java를 참고해주세요.

 // 일반 Activity 에서의 adlib 연동
 private AdlibManager _amanager; 

 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     // 각 애드립 액티비티에 애드립 앱 키값을 필수로 넣어주어야 합니다. 
     _amanager = new AdlibManager(AdlibTestProjectConstans.ADLIB_API_KEY); 
     _amanager.onCreate(this); 

     // 테스트 광고 노출
     _amanager.setAdlibTestMode(AdlibTestProjectConstans.ADLIB_TEST_MODE);
 }
 
 // background에서 불필요한 광고 호출을 막기위해 onResume, onPause, onDestroy에 아래와같이 호출해주세요.
 protected void onResume() {
     _amanager.onResume(this);
     super.onResume();
 }

 protected void onPause() {
     _amanager.onPause(this);
     super.onPause();
 }
   
 protected void onDestroy() {
     _amanager.onDestroy(this);
     super.onDestroy();
 }
			

3-2. 광고 호출

보다 자세한 내용은 샘플 프로젝트의 AdlibTestProjectActivity.java 파일을 참조해주세요.


public class AdlibTestProjectActivity extends AdlibActivity
처음으로 실행되는 Activity 에서 광고 스케줄링 정보를 받아올 수 있도록 아래와 같이 먼저 호출합니다.

protected void initAds()
{
    // 광고 스케줄링 설정을 위해 아래 내용을 프로그램 실행시 한번만 실행합니다.
    //  (처음 실행되는 activity에서 한번만 호출해주세요.)
    // 광고 subview 의 패키지 경로를 설정합니다. (실제로 작성된 패키지 경로로 수정해주세요.)
    // 일반 Activity 에서는 AdlibManager 를 동적으로 생성한 후 아래 코드가 실행되어야 합니다. (AdlibTestProjectActivity4.java)


    // 쓰지 않을 광고플랫폼은 삭제해주세요.
    AdlibConfig.getInstance().bindPlatform("ADMIXER", "test.adlib.project.ads.SubAdlibAdViewAdmixer");
    AdlibConfig.getInstance().bindPlatform("ADAM", "test.adlib.project.ads.SubAdlibAdViewAdam");
    AdlibConfig.getInstance().bindPlatform("ADMOB", "test.adlib.project.ads.SubAdlibAdViewAdmob");
    AdlibConfig.getInstance().bindPlatform("AMAZON", "test.adlib.project.ads.SubAdlibAdViewAmazon");
    AdlibConfig.getInstance().bindPlatform("MOBCLIX", "test.adlib.project.ads.SubAdlibAdViewMobclix");
    AdlibConfig.getInstance().bindPlatform("CAULY", "test.adlib.project.ads.SubAdlibAdViewCauly");
    AdlibConfig.getInstance().bindPlatform("FACEBOOK", "test.adlib.project.ads.SubAdlibAdViewFacebook");
    AdlibConfig.getInstance().bindPlatform("INMOBI", "test.adlib.project.ads.SubAdlibAdViewInmobi");
    AdlibConfig.getInstance().bindPlatform("MEZZO", "test.adlib.project.ads.SubAdlibAdViewMezzo");
    AdlibConfig.getInstance().bindPlatform("MMEDIA", "test.adlib.project.ads.SubAdlibAdViewMMedia");
    AdlibConfig.getInstance().bindPlatform("MOBFOX", "test.adlib.project.ads.SubAdlibAdViewMobfox");
    AdlibConfig.getInstance().bindPlatform("MOPUB", "test.adlib.project.ads.SubAdlibAdViewMopub");
    AdlibConfig.getInstance().bindPlatform("SHALLWEAD", "test.adlib.project.ads.SubAdlibAdViewShallWeAd");
    AdlibConfig.getInstance().bindPlatform("TAD", "test.adlib.project.ads.SubAdlibAdViewTAD");
    AdlibConfig.getInstance().bindPlatform("TNK", "test.adlib.project.ads.SubAdlibAdViewTNK");
    
    // 쓰지 않을 플랫폼은 JAR 파일 및 test.adlib.project.ads 경로에서 삭제하면 최종 바이너리 크기를 줄일 수 있습니다.

    // SMART* dialog 노출 시점 선택시 / setAdlibKey 키가 호출되는 activity 가 시작 activity 이며
    // 해당 activity가 종료되면 app 종료로 인식합니다.
    // adlibr.com 에서 발급받은 api 키를 입력합니다.
    // https://sec.adlibr.com/admin/dashboard.jsp

    // 각 애드립 액티비티에 애드립 앱 키값을 필수로 넣어주어야 합니다.
    setAdlibKey(AdlibTestProjectConstans.ADLIB_API_KEY);

    // 테스트 광고 노출
    setAdlibTestMode(AdlibTestProjectConstans.ADLIB_TEST_MODE);
}
  • 실제 구현된 광고 플랫폼 뷰를 프로젝트에 연결합니다.
  • AdlibConfig.getInstance().bindPlatform("INMOBI","test.adlib.project.ads.SubAdlibAdViewInmobi");
  • 위 패키지 경로는 실제 구현된 경로로 수정이 되어야 하며 샘플 프로젝트에서는 test.adlib.project.ads 경로 아래에 구현되어 위와 같이 연결되었습니다.
  • setAdlibTestMode(true)로 테스트 광고를 노출하여 어플리케이션 상용 전에 테스트를 진행할 수 있습니다. 단, 상용 시엔 해당 메서드를 꼭 제거해야 합니다.

3-3. 광고 View 연결

내용은 샘플 프로젝트의 AdlibTestProjectActivity.java 파일을 참조해주세요.


setContentView(R.layout.main);
initAds();

// 실제 광고 호출이 될 adview 를 연결합니다.
this.setAdsContainer(R.id.ads);


layout/main.xml은 아래와 같이 구현되었습니다.

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

     <!-- adlib adview -->
     <com.mocoplex.adlib.AdlibAdViewContainer
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:id="@+id/ads"
     isDefaultBanner="true" />
</LinearLayout>

위와같이 xml에서 com.mocoplex.adlib.AdlibAdViewContainer 로 구현된 id/ads를

    this.setAdsContainer(R.id.ads);

최종적으로 Activity에 연결합니다.

Activity 에 광고를 연결하면 Adlib 대쉬보드에서 설정한 광고가 노출됩니다.


전면배너 띠배너

3-4. 두 번째 Activity 설정

보다 자세한 내용은 샘플 프로젝트의 AdlibTestProjectActivity2.java 파일을 참조해주세요.

이미 전역적인 설정을 첫 번째 Activity 에서 수행하였기 때문에 두 번째 이후의 Activity 에서는 아래와 같이 광고 뷰를 bind 하기만 하면 됩니다.


  public class AdlibTestProjectActivity2 extends AdlibActivity {

         // 애드립 광고를 테스트 하기 위한 키 입니다.
        private String ADLIB_API_KEY = "53858972e4b0ef94c0636d85";

        /** Called when the activity is first created. */
        @Override
        protected void onCreate(Bundle savedInstanceState) {

              super.onCreate(savedInstanceState);
              setContentView(R.layout.main2);

               // 각 애드립 액티비티에 애드립 앱 키값을 필수로 넣어주어야 합니다.
              this.setAdlibKey(ADLIB_API_KEY);
              setAdlibTestMode(true); // 테스트 광고 노출로, 상용일 경우 꼭 제거해야 합니다.
              this.setAdsContainer(R.id.ads);

        }
  }
  

3-5. 광고 View 동적 생성

보다 자세한 내용은 샘플 프로젝트의 AdlibTestProjectActivity3.java 파일을 참조해주세요.

광고 뷰를 xml 이 아닌 아래와 같이 동적으로 코드상에서 생성 및 연결이 가능합니다.


  // 동적으로 adview 를 생성합니다.
  avc = new com.mocoplex.adlib.AdlibAdViewContainer(AdlibTestProjectActivity3.this);

  ViewGroup vg = (ViewGroup)findViewById(R.id.maincontainer);
  vg.addView(avc);

  // 동적으로 생성한 adview 에 스케줄러를 바인드합니다.
  bindAdsContainer(avc);
  

3-6. 타 광고 플랫폼과의 연결

  실제 광고 플랫폼의 뷰를 포함하는 패키지이며 SubAdlibAdViewCore 클래스를 상속받아 제작됩니다.

  public void query()
  public void gotAd()

  //스케줄러에 의해 위의 함수가 호출되며 광고를 수신한 경우 gotAd 를 호출하며 위의 함수 호출로 실제로 AdlibAdViewContainer 를 통해 화면에 보여지게 됩니다.

  위의 패키지명은 필요에 의해 임의의 프로젝트 경로로 변환이 가능하며 변환된 경로는

  AdlibConfig.getInstance().bindPlatform("INMOBI","test.adlib.project.ads.SubAdlibAdViewInmobi");

  를 통해 실제 경로로 변경해야합니다.
  

테스트 프로젝트의 test.adlib.project.ads 패키지 안에는 제휴 및 일반 플랫폼의 view 가 구현되어 있습니다.
기본적인 모든 구현은 이미 완성되어 있으며 실제 각 플랫폼 구현부에서의 ID 부분만 실제 발급 받은 ID로 교체하여 사용합니다.
AndroidManifest.xml 에 ID 를 추가해야 하는 경우도 있습니다. (각 플랫폼의 SDK 문서 참조)

3-7. Dialog를 통한 광고

Activity에서 requestAdDialog() 매서드를 통해 광고를 요청합니다.

이후 광고 노출이 필요한 시점에 showAdDialog() 메서드를 통해 dialog를 이용하여 광고를 노출할 수 있습니다.

AdlibDialogAdListener() 로 버튼 액션에 대한 기능을 추가할 수 있습니다.

자세한 내용은 샘플 프로젝트 AdlibTestProjectActivity.java 파일을 참고해주세요.
샘플 프로젝트에서는 종료 대화상자 광고를 예시로 구현하였습니다.

(종료 dialog 광고는 세로 화면일 경우에만 적용됩니다.)


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

                    ....

                    // 다이얼로그 광고 요청
                    adlibManager.requestAdDialog(new Handler() {
                        @Override
                        public void handleMessage(Message msg) {
                            switch (msg.what) {
                                case AdlibManager.DID_SUCCEED:
                                    break;

                                case AdlibManager.DID_ERROR:
                                    break;
                            }
                        }
                    });

                    ...
                    
                }

               @Override
                public void onBackPressed() {
                    // 다이얼로그 광고 사용 가능 여부 확인
                    // 광고가 없는 경우 타 플랫폼이나 매체 내부 동작 처리가 필요한 경우 사용가능한 함수
                    // adlibManager.isAvailableAdDialog();

                    // 종료 대화상자 광고를 노출하기 위해서 호출합니다.
                    adlibManager.showAdDialog("취소", "확인", "종료하시겠습니까?");

                    // 필요시 아래와 같이 색상과 클릭 액션을 변경할 수 있습니다.
                    //backgroundColor, backgroundColor(click), textColor, textColor, textColor(click), lineColor
                    // int[] colors = new int[]{0xffffffff, 0xffa8a8a8, 0xff404040, 0xff404040, 0xffdfdfdf};
                    // adlibManager.showAdDialog("취소", "확인", "종료하시겠습니까?", colors, new AdlibDialogAdListener() {
                    //
                    //     @Override
                    //     public void onLeftClicked() {
                    //     }
                    //
                    //     @Override
                    //     public void onRightClicked() {
                    //     }
                    //
                    // });
                }
              

3-8. 전면배너 호출 유형

대쉬보드의 간단한 설정으로 전면배너를 자동 노출할 수 있습니다.
또한 그 외의 이벤트 발생 시에는 직접 호출하여 전면배너를 노출할 수 있습니다.
전면배너를 직접 호출하는 경우에는 다양한 플랫폼을 스케쥴링할 수 있습니다.

AdlibActivity를 상속하는 경우 AdlibManager를 생성하는 경우
loadFullInterstitialAd(); _amanager.loadFullInterstitialAd(this);

» 자동 호출

  • 애드립 대쉬보드의 [전면배너 스케쥴 설정]에서 ‘시작시 노출’이나 ‘종료시 노출’을 활성화 상태로 설정하면 추가 구현없이 해당 시점에 전면배너가 노출됩니다.
  • 단, 자동 노출 기능은 스케쥴링을 사용할 수 없으며, 애드립에서 제공하는 전면배너 노출만 가능합니다.

» 직접 호출

  • 전면배너를 직접 호출하여 사용할 경우, 대쉬보드에서 원하는 플랫폼을 선택하여 스케쥴링할 수 있습니다.
    애드립 전면배너 노출비중에 따라 애드립 전면배너 또는 설정된 광고 플랫폼 순서대로 전면배너를 호출합니다.
  • 대쉬보드를 설정하고, 전면배너 직접 호출을 원하는 부분에 아래와 같은 형식으로 구현합니다. 상세 구현부는 샘플 프로젝트를 참고해주세요.

3-9. 광고 Callback

애드립 광고의 수신 성공, 실패 이벤트 처리가 필요한 경우 handler를 이용할 수 있습니다.

» 띠배너

    this.setAdsHandler(new Handler() {
          public void handleMessage(Message message) {
          try
          {

              switch (message.what) {
                    case AdlibManager.DID_SUCCEED:
                            Log.d("ADLIBr", "[Banner] onReceiveAd " + (String)message.obj);
                            break;
                    case AdlibManager.DID_ERROR:
                            Log.d("ADLIBr", "[Banner] onFailedToReceiveAd " + (String)message.obj);
                            break;
              }
          }

            catch(Exception e){
            }
            }
    });
    

» 전면배너

    loadFullInterstitialAd(new Handler() {
        public void handleMessage(Message message) {
          try
          {
                switch (message.what) {
                    case AdlibManager.DID_SUCCEED:
                      Log.d("ADLIBr", "[Interstitial] onReceiveAd " + (String)message.obj);
                      break;

                    // 전면배너 스케줄링 사용시, 각각의 플랫폼의 수신 실패 이벤트를 받습니다.
                    case AdlibManager.DID_ERROR:
                      Log.d("ADLIBr", "[Interstitial] onFailedToReceiveAd " + (String)message.obj);
                      break;

                    // 전면배너 스케줄로 설정되어있는 모든 플랫폼의 수신이 실패했을 경우 이벤트를 받습니다.
                    case AdlibManager.INTERSTITIAL_FAILED:
                      Log.d("ADLIBr", "[Interstitial] All Failed.");
                      break;

                    case AdlibManager.INTERSTITIAL_CLOSED:
                      Log.d("ADLIBr", "[Interstitial] onClosedAd " + (String)message.obj);
                      break;
                }

          }

          catch(Exception e){
          }

            }

    });
    

주의

  • Proguard를 이용하여 암호화 하는 경우 proguard configuration 파일 수정이 필요합니다.
    자세한 구현 내용은 샘플 프로젝트의 proguard.cfg 파일 또는
    https://github.com/mocoplex/adlibr-SDK-android/blob/master/adlibrTestProject/app/proguard-rules.pro
    위 주소를 참고해 주세요.
  • 애드립은 내부 스케줄링 정보를 저장하기 위해 document 폴더 안에 캐쉬 데이터를 저장합니다.
    DocumentPath/Adlib-data/ 경로에 캐쉬 데이터를 저장하므로 해당 폴더를 삭제하지 말아주세요.

자주묻는 질문(FAQ)

Q. 꼭 AdlibActivity 를 상속받아 구현해야 하나요?
A. 애드립과 관련한 기본적인 구현은 AdlibManager 클래스에서 구현되었으며,
이 클래스를 멤버로 Activity status 에 맞추어 멤버 함수를 호출하여 사용 가능합니다.

https://github.com/mocoplex/adlibr-SDK-android/blob/master/adlibrTestProject/src/test/adlib/project/AdlibTestProjectActivity4.java
Q. 각 나라에 맞게 광고 스케줄을 달리 적용하고 싶습니다. (지역 타게팅)
A. 애드립의 앱 스케줄 설정 화면에서, 타게팅을 원하는 나라를 추가하여 손쉽게 노출전략을 설정할 수 있습니다.
Q. proguard 적용 후 광고, 대화상자가 보이지 않습니다.
A. 실제 bind하는 패키지의 난독화로 광고가 보이지 않는 현상이 나타날 수 있습니다.
[ -keep 옵션 ] 을주어 아래코드에서 사용된 패키지 경로의 난독화를 방지합니다.
자세한 구현내용은 테스트 프로젝트의 proguard.cfg 파일 또는

https://github.com/mocoplex/adlibr-SDK-android/blob/master/adlibrTestProject/app/proguard-rules.pro

위 주소를 참고해 주세요.

정리

애드립 연동이 마무리되었습니다.

## 실제 프로젝트에 애드립을 연동하기 위해 ##

  • 각 플랫폼의 ID 발급 및 SDK 다운로드
  • SDK 프로젝트에 라이브러리 추가
  • AndrodiManifest.xml 수정
  • test.adlib.project.ads 안의 광고 ID 설정 부분 수정
  • 광고를 보여줄 Activity 의 AdlibActivity 상속
    (일반 Activity의 경우에는 Adlib Manager 생성 및
    onCreate, onResume, onPause, onDestroy 호출)
  • AdlibConfig.getInstance() 를 통한 전역적인 광고 설정
    (일반 Activity의 경우 이 작업보다 Adlib Mnager의 생성 및 onCreate가 먼저 이루어져야 합니다.)
  • AdlibAdViewContainer 생성 및 bind