처음부터 차근차근

이벤트 처리 본문

프로그래밍/Android

이벤트 처리

_soyoung 2022. 3. 28. 13:30
반응형

배경 지식

Android에서 UI 작업은 메인 스레드에서만 할 수 있다.

 

이유1. Android UI가 <싱글 스레드 모델>을 따르고 있기 때문(중요)

싱글 스레드 모델 : 안드로이드 화면을 구성하는 뷰나 뷰그룹을 하나의 스레드에서만 담당하는 원칙

<싱글 스레드 모델 규칙>
1. 메인 스레드를 중단하지 않기
2. 안드로이드 UI 툴킷은 오직 메인 스레드(UI 스레드)에서만 접근할 수 있도록 하기

 

이유2. 앱의 속도가 느려지기 때문

메인 스레드에서 UI를 맡아서 작업하는 데, UI 작업 말고도 다른 시간이 많이 걸리는 작업까지 메인 스레드에서 도맡아 하면 앱의 속도가 현저히 느려진다.

그래서 UI를 제외한 다른 작업들은 다른 스레드에다 맡겨 분리하는 방법을 선택했다.

 

 

메인 스레드는 기본적으로 looper을 가진다.

 

looper은 Message Queue를 가진다.

 

 

handler와 looper, 메세지 큐(Message Queue)

메세지란 명령이다.

예를 들어 a(); 이렇게 함수 a를 호출하는 것을 하나의 메세지라고 생각하면 된다. 

 

메세지 큐는 생긴 메세지들을 차곡 차곡 담아두는 저장소(큐)이다.

 

안드로이드의 looper은 메세지 큐의 변화를 감시하는 감시자이다. 메세지 큐에 처리해야될 메세지가 생기면 handler에게 보내서 처리하라고 요청한다.

 

handler은 looper에게서 요청받은 메세지를 메인 스레드에서 처리한다.
이때 handler은 받은 메세지를 handleMessage() 함수의 매개변수로 넣어 함수를 실행한다.

그래서 handler는 워킹 스레드와 메인 스레드를 연결해주는 것이라고도 볼 수 있다.

 

 

handler 예제

public class MainActivity extends AppCompatActivity {

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

        doInitialTask();
    }

    private void doInitialTask() {

        Handler handler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                Log.d("______________", String.valueOf(msg.what));
                
                Intent i = new Intent(MainActivity.this, MainActivity2.class);
                startActivity(i);
                finish();
            }
        };

        handler.sendEmptyMessageDelayed(7, 3 * 1000);
    }
}

 

 

string xml로 넣기

app \ src \ main \ res \ values \ strings.xml

<resources>
    <string name="app_name">chap4</string>
    <string name="mybutton">나의 버튼</string> <!--추가-->
</resources>

 

activity_main.xml

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/mybutton" />

 

 

 

이미지 버튼

<ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/btn_dialog" />

결과

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/mybutton"
        android:drawableRight="@android:drawable/btn_dialog" />

결과

 

 

 

MainActivity.java

public class MainActivity extends AppCompatActivity {

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


    public void onClicked(View view) { // 추가
        Toast.makeText(this, "ImageButton Click Test", Toast.LENGTH_LONG).show();
    }
}

 

activity_main.xml

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="onClicked"
    android:drawableRight="@android:drawable/btn_dialog" />

 

 

 

Snackbar

MainActivity.java

public class MainActivity extends AppCompatActivity {

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


    public void onClicked(View view) {
        Snackbar s = Snackbar.make(view, "Snackbar", Snackbar.LENGTH_INDEFINITE);
        s.setAction("확인", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                s.dismiss();
            }
        });
        
        s.show();
    }
}

결과

 

 

 

커스텀 버튼

public class MainActivity extends AppCompatActivity {

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


    public void onClicked(View view) {
        view.setSelected(true);
    }
}

 

 

activity_main.xml

<ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClicked"
        android:background="@drawable/state" />

 

drawable \ state.xml(만들기!)

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


    <item android:state_pressed="true" android:drawable="@android:drawable/btn_minus" />
    <item android:state_selected="true" android:drawable="@android:drawable/btn_plus" />
    <item android:drawable="@android:drawable/btn_star" />


</selector>

결과1

 

 

 

무명클래스로 이벤트 처리

<?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"
    android:gravity="center"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnTest"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="무명클래스 테스트" />

</LinearLayout>
public class MainActivity extends AppCompatActivity {

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

        Button btn = (Button)findViewById(R.id.btnTest);
        btn.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        Toast.makeText(MainActivity.this, "Clicked...", Toast.LENGTH_SHORT).show();
                    }
                }
        );
    }

}

결과

 

 

 

 

출처 : 안드로이드프로그래밍(22-1학기)김용남교수 강의 내용 변형 및 요약

참고 : https://bite-sized-learning.tistory.com/142

https://medium.com/@sunminlee89/looper%EC%99%80-handler%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-d05e28929d4d

반응형

'프로그래밍 > Android' 카테고리의 다른 글

Android 메뉴  (0) 2022.04.12
리스너 객체  (2) 2022.04.08
android view2  (0) 2022.03.25
사용자 인터페이스 기초 - 뷰  (0) 2022.03.16
애플리케이션의 기본구조  (0) 2022.03.15
Comments