본문 바로가기
개발(Development)/Android(안드로이드)

[안드로이드] this와 MainActivity.this의 개념, 차이

by 카레유 2021. 7. 13.

Android를 개발하다보면 어떤 때는 this를 쓰고, 어떤 때는 MainActivity.this 형태를 사용한다.

심지어 두개를 바꿔서 사용하면 에러가 발생할 때도 있다.

 

이 둘의 개념과 차이, 그리고 사용법을 정리한다.


# Java의 this

1. 메서드 내부에서 사용되면, 클래스가 생성할 본인(인스턴스|객체) 자체를 가르키며,

2. 생성자 함수 내부에서는 this()형태로 사용하여, 오버로딩된 다른 생성자 함수를 호출한다.


# 안드로이드의 this와 MainActivity.this

안드로이드에서는 this 외에 MainActivity.this 같이 "클래스명.this" 형태가 종종 사용된다.

예를 들어 버튼을 누르면 액티비티를 띄우는 아래의 코드를 보자.

 

 

1. 익명 클래스로 View.OnclickListenr 인터페이스를 구현하는 방식

 

public class MainActivity extends AppCompatActivity {

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

        Button button = findViewById(R.id.button);
        
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            
            	// MainActivity.this를 첫번째 인자로 넣어준다.
                Intent intent = new Intent(MainActivity.this, MainActivity2.class);
                startActivity(intent);
            }
        });

    }
}

 

Intent 생성자의 첫번째 인자(Context타입)로 MainActivity.this 를 넣어준 위 코드는 정상 동작한다.

그러나 MainActivity.this 부분을  this로 바꾸면 에러가 발생하면서 빌드조차 되지 않는다.

 

 

그런데 이벤트 리스너 연결 방식을 바꾸어 보면 어떻게 될까?

 

 

2. View.OnClickerListener 인터페이스를 implements하고, onClick()메서드를 오버라이딩 하는 방식

 

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

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

        Button button = findViewById(R.id.button);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
    
    	// this를 첫번째 인자로 넣어준다.
        Intent intent = new Intent(this, MainActivity2.class);
        startActivity(intent);
    }

}

 

위의 코드는 Intent 생성자의 인자로 this만 넣어줘도 정상동작한다.

또한 MainActivity.this를 넣어주어도 정상동작한다.

 

 

어떻게 된 영문일까?

 

위의 두가지 방식에서 this가 가르키는 대상이 다르기 때문에 이런 일이 발생한다.


1. 첫번째 익명 클래스 생성 방식의 경우

View.OnClickListener 인터페이스 내부에서 onClick메서드가 오버라이딩(구현) 된다.

따라서 onClick메서드 내부에서 this를 사용하면, this는 View.OnClickListener를 가르키게 된다.

 

 Intnet 생성자의 첫번째 인자에는 Context객체를 넣어줘야 하는데,

View.OnClickListener 인터페이스는 Context를 상속받고 있지 않아서 에러가 발생하게 되는 것이다.

 

그래서 MainActivity의 this를 가르킨다고 명시하기 위해서 MainActivity.this 라는 형식을 사용하는 것이다.

 

2. 두번째 View.OnClickListener 인터페이스를 implements하는 경우

onClick 메서드의 오버라이딩(구현)이 MainActivity 클래스 내부에서 이루어진다.

따라서 onClick 메서드 내부에서 this를 사용하면 MainActivity 를 가르키게 된다.

 

MainActivity는 Activity 클래스를 상속 받으며, Activity는 Context를 상속받으므로, 결과적으로 this는 Context의 자식이 된다.

따라서 Intent 생성자의 첫번째 자리를 꿰찰 수 있게 되는 것이다.


# 주의사항

단, 클래스명.this는 해당 클래스 내부에서만 사용 가능한듯 하다.

 

주로 익명 클래스 방식으로 인터페이스의 메서드를 오버라이딩(구현)할 때 많이 사용하게 된다.

그 외의 일반적인 경우에는 Java문법에 맞게 그냥 this를 사용하는게 좋은 것 같다.


사실 조금 더 깊게 들어가려면 Context 자체에 대해 다루어야 하지만,

이 부분은 다음으로 기회에.

 

댓글