상세 컨텐츠

본문 제목

[Android Studio] 5-1. 네트워킹

Emzi(김민근)/android

by Emzi 2020. 2. 27. 13:42

본문

*해당 포스팅은 커넥트 재단의 edwith-[부스트 코스] 안드로이드 프로그래밍의 강의 자료를 바탕으로 작성되었습니다.

1.Thread

스레드는 동시작업을 위한 한 단위 입니다. 기본적으로 앱이 실행되면 메인 스레드가 실행 됩니다.

스레드는 원할때마다 새로 만들수 있는데 각 스레드는 독립적으로 실행됩니다.  다만 메인 스레드에서 관리하는 UI에 접근하기 위해선 직접 메인 스레드에 접근하는것이 아니라 핸들러를 사용하여 접근해야합니다. 핸들러는 내부적으로 큐를 이용하여 순서대로 처리를 해주어 동시 접근의 문제를 해결해줍니다. 

<예제>

button.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
                Background thread = new Background();
                thread.start();}
                
button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("현재 값: "+  value);
            }
        });
    }
    
    
class Background extends Thread{  //스레드 생성
        boolean running = false;
        public void run(){
            running = true;
            while (running){
                value += 1;
                //textView.setText("현재 값: "+  value); 메인쓰레드 바로 접근시 오류

                try{
                Thread.sleep(1000);
                } catch (Exception e) {}
            }
        }
    }

 

스레드를 생성하여 1초마다 value값을 증가 시켜주었습니다. 하지만 스레드에 settext를 바로 넣게 되면 메인스레드가 관리하는 UI에 바로 접근하기 때문에 에러가 납니다. 때문에 1초마다 텍스트에 숫자를 증가시켜주기위하여 핸들러를 사용합니다.

<에제2-핸들러사용>

class Background extends Thread{
        boolean running = false;
        public void run(){
            running = true;
            while (running){
                value += 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);
            Bundle bundle = msg.getData();
            int value = bundle.getInt("value");
            textView.setText("현재 값: "+ value);
        }
    }
}

 

이처럼 핸들러를 사용하여 UI에 접근이 가능하도록 해주었습니다.

<예제 3- 간단히>

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

                new Thread(new Runnable() {
                    int value = 0;
                    boolean running = false;
                    @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();

또한 이렇게 이너클래스로 복잡하게 주는 방법보단 버튼에 스레드 객체를 생성하는 방법도 존재합니다 이경우 코드가 간단해집니다.

2.AsyncTask

AsyncTask는 스레드와 핸들러의 복잡함을 덜어 줄수 있는 상속 클래스 입니다. 

doInBackground()메소드는 스레드를 구현하며 onProgressUpdate()메소드는 UI에 접근하도록 도와줍니다. onPostExcute()메소드는 스레드가 완료될때 실행되는 메소드입니다.

<예제 - AsyncTask>

class ProgressTask extends AsyncTask<String,Integer,Integer>{
        @Override
        protected Integer doInBackground(String... strings) { //스레드 부분
            int value =0;
            while (true){
                if(value>100)break;
                value += 2;
                publishProgress(value); // onProgressUpdate로 전
                try {
                    Thread.sleep(100);
                } catch (Exception e){}
            }
            return value;
        }

        @Override
        protected void onPostExecute(Integer integer) { //끝나면
            super.onPostExecute(integer);
            Toast.makeText(getApplicationContext(),"완료됨.",Toast.LENGTH_LONG).show();
        }

        @Override
        protected void onProgressUpdate(Integer... values) { //진행중일때 UI접근
            super.onProgressUpdate(values);
            progressBar.setProgress(values[0].intValue());
        }
    }

 

 

관련글 더보기

댓글 영역