λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
APP/ANDROID

[λΆ€μŠ€νŠΈμ½”μŠ€] μŠ€λ ˆλ“œ(Thread)

by mingzoo 2020. 3. 4.

μŠ€λ ˆλ“œ(Thread)

μ–΄λ– ν•œ ν”„λ‘œκ·Έλž¨μ—μ„œ, ν”„λ‘œμ„ΈμŠ€ λ‚΄μ—μ„œ μ‹€ν–‰λ˜λŠ” νλ¦„μ˜ λ‹¨μœ„λ₯Ό λ§ν•œλ‹€.

λ™μ‹œ μž‘μ—…μ„ μœ„ν•œ ν•œ λ‹¨μœ„

메인 μŠ€λ ˆλ“œ : 앱을 μ‹€ν–‰ν•˜λ©΄ ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œκ°€ μ‹œμž‘λ  λ•Œ, 이의 μŠ€λ ˆλ“œλ₯Ό 가리킴

μŠ€λ ˆλ“œκ°€ λ™μž‘ν•˜λŠ” 방식은 ν‘œμ€€ μžλ°”μ™€ λ™μΌν•˜μ§€λ§Œ, 차이점이 μžˆλ‹€λ©΄ μ•ˆλ“œλ‘œμ΄λ“œμ—μ„œλŠ” λ©”λͺ¨λ¦¬ μ†ŒμŠ€μ™€ UI에 직접 μ ‘κ·Όν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— ν•Έλ“€λŸ¬(Handler)κ°€ λ°˜λ“œμ‹œ μ‚¬μš©λ˜μ–΄μ•Όν•œλ‹€.

μ™œλƒν•˜λ©΄, UIλ‚˜ 파일과 같은 λ¦¬μ†ŒμŠ€λŠ” μ—¬λŸ¬ 개의 μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— μ ‘κ·Όν–ˆμ„ λ•Œ μ‹œμŠ€ν…œμ—μ„œ μ–΄λ–€ 것을 λ¨Όμ € μ²˜λ¦¬ν•΄μ•Ό ν•˜λŠ”μ§€ λͺ¨λ₯΄λŠ” λ¬Έμ œκ°€ λ°œμƒν•  수 있기 λ•Œλ¬Έμ΄λ‹€.

ν•Έλ“€λŸ¬(Handler)

λ©”μ‹œμ§€ 큐λ₯Ό μ΄μš©ν•΄ 메인 μŠ€λ ˆλ“œμ—μ„œ μ²˜λ¦¬ν•  λ©”μ‹œμ§€ 전달

νŠΉμ • λ©”μ‹œμ§€κ°€ 미래의 μ–΄λ–€ μ‹œμ μ—μ„œ μ‹€ν–‰λ˜λ„λ‘ μŠ€μΌ€μ€„λ§ κ°€λŠ₯

 

obtainMessage()

호좜의 결과둜 λ©”μ‹œμ§€ 객체λ₯Ό λ¦¬ν„΄λ°›κ²Œ ν•œλ‹€

 

sendMessage()

λ©”μ‹œμ§€νμ— λ„£λŠ”λ‹€

 

handleMessage()

λ©”μ†Œλ“œμ— μ •μ˜λœ κΈ°λŠ₯이 μˆ˜ν–‰λœλ‹€

μ½”λ“œκ°€ μˆ˜ν–‰λ˜λŠ” μœ„μΉ˜λŠ” μƒˆλ‘œ λ§Œλ“  μŠ€λ ˆλ“œκ°€ μ•„λ‹Œ 메인 μŠ€λ ˆλ“œ

 

 


κΈ°λ³Έ μŠ€λ ˆλ“œ μ‚¬μš©ν•˜κΈ°

λ°±κ·ΈλΌμš΄λ“œμ—μ„œ value값을 μ¦κ°€μ‹œμΌœ λ²„νŠΌ2λ₯Ό μ‚¬μš©ν•΄ 값을 ν™•μΈν•œλ‹€.

단점 : λ²„νŠΌ 2λ₯Ό λˆŒλŸ¬μ•Όλ§Œ μž‘μ—…ν•œ 것을 ν™”λ©΄μœΌλ‘œ 확인가λŠ₯

package com.example.thread;

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

import android.content.ContentProviderClient;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView textView;

    int value = 0;

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

        textView = findViewById(R.id.textView);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new TextView.OnClickListener() {
            @Override
            public void onClick(View v) {
                BackgroundThread thread = new BackgroundThread();
                thread.start();
            }
        });

        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("ν˜„μž¬ κ°’ : " + value);
            }
        });
    }

    //μŠ€λ ˆλ“œ κ΅¬ν˜„ν•œ 객체
    class BackgroundThread extends Thread {
        boolean running = false;

        public void run() {
            running = true;
            //1μ΄ˆλ§ˆλ‹€ 벨λ₯˜κ°’ 1μ”© μ¦κ°€μ‹œν‚€λŠ” μŠ€λ ˆλ“œμž„
            while ((running)) {
                value += 1;
                //textView.setText("ν˜„μž¬ κ°’ : " + value); 
                //λ§Œμ•½μ— μ—¬κΈ°μ„œ button2같은 ν…μŠ€νŠΈUI 값을 λ°”κΏ”μ£ΌλŠ” κ±Έ ν•œλ‹€λ©΄ μ—λŸ¬κ°€ λ°œμƒ
                //μ™œλƒν•˜λ©΄ 메인 μŠ€λ ˆλ“œκ°€ μ‚¬μš©λ˜μ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ—!
                //λ©”μΈμ•‘ν‹°λΉ„ν‹°λŠ” λ©”μΈμŠ€λ ˆλ“œκ°€ 이미 μ μœ ν•˜κ³ μžˆκΈ° λ•Œλ¬Έμ— λ‹€λ₯Έ μŠ€λ ˆλ“œμ—μ„œ 접근을 ν•˜λ©΄ λ°λ“œλ½μ΄ κ±Έλ € μ—λŸ¬κ°€μƒκΉ€
                try {
                    Thread.sleep(1000);
                } catch (Exception e) { }
            }
        }
    }
}

 

ν•Έλ“€λŸ¬ μ‚¬μš©ν•˜κΈ°

기본적인 ν•Έλ“€λŸ¬ μ‚¬μš©μ„ μ΄μš©ν•˜μ—¬ ν™•μΈλ²„νŠΌμ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³ , μŠ€λ ˆλ“œμ—μ„œ λ™μ μœΌλ‘œ UI에 μ ‘κ·Όν•  수 있게 ν•˜μ˜€λ‹€.

package com.example.thread;

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

import android.content.ContentProviderClient;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    TextView textView;

    //int value = 0;

    ValueHandler handler = new ValueHandler();

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

        textView = (TextView) findViewById(R.id.textView);

        //첫번째 λ²„νŠΌ : μŠ€λ ˆλ“œλ₯Ό λ§Œλ“€μ–΄μ„œ μ‹€ν–‰
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BackgroundThread thread = new BackgroundThread();
                thread.start();
            }
        });

        Button button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               // textView.setText("ν˜„μž¬ κ°’ :" + value);
            }
        });
    }

    //thread.startμ—μ„œ μŠ€νƒ€νŠΈκ°€ λ¨Όμ € μ‹€ν–‰λ˜λŠ” 것이 μ•„λ‹ˆλΌ, run λ©”μ†Œλ“œκ°€ μ‹€ν–‰
    class BackgroundThread extends Thread{
        int value = 0;
        boolean running = false;
        public void run() {
            running = true;
            while(running){
                value += 1; //1μ΄ˆλ§ˆλ‹€ 1μ”© 증가
                //textView.setText("ν˜„μž¬ κ°’:" + value);
                //μ—λŸ¬λ°œμƒ:λ©”μΈμŠ€λ ˆλ“œλ§Œ μ ‘κ·Όκ°€λŠ₯

                Message message = handler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("value",value);
                message.setData(bundle);
                handler.sendMessage(message);
                try{
                    Thread.sleep(1000);
                }catch(Exception e){}
            }
        }
    }
//μŠ€λ ˆλ“œμ—μ„œ λ©”μ‹œμ§€λ₯Ό 보내면 ν•Έλ“€λŸ¬μ—μ„œ λ°›λŠ”λ‹€.
    class ValueHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            //UI 직접접근가λŠ₯

            Bundle bundle = msg.getData();
            int value = bundle.getInt("value");
            textView.setText("ν˜„μž¬ κ°’:" + value);
        }
    }
}

 

ν•Έλ“€λŸ¬&post 이용

μŠ€λ ˆλ“œ 클래슀 μ •μ˜ => μŠ€λ ˆλ“œ μ•ˆμ— runnable객체λ₯Ό λ„£λŠ” 것

클래슀 μœ—λΆ€λΆ„μ— Handler handler2 = new Handler(); 둜 μƒˆλ‘œμš΄ ν•Έλ“€λŸ¬λ₯Ό μ •μ˜ν•΄μ€€λ‹€.

postλ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μœ„μ˜ μ½”λ“œλ³΄λ‹€ 더 κ°„νŽΈν•˜κ²Œ μŠ€λ ˆλ“œ μ•ˆμ—μ„œ UI 접근이 κ°€λŠ₯ν•˜κ²Œ ν•˜μ˜€λ‹€.

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //BackgroundThread thread = new BackgroundThread();
                //thread.start();

                //μŠ€λ ˆλ“œλ₯Ό runnable객체λ₯Ό implementν•˜λŠ” 것
                int value = 0;
                boolean running = false;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        running = true;
                        while(running){
                            value += 1;

                            handler2.post(new Runnable() {
                                @Override
                                public void run() {
                                    textView.setText("ν˜„μž¬ κ°’ : "+value);
                                    //ν•Έλ“€λŸ¬ μ•ˆμ—μ„œ μ‹€ν–‰
                                }
                            });
                            try{
                                Thread.sleep(1000);
                            }catch(Exception e){}
                    }
                }).start();
            }
        });

 

 

728x90