본문 바로가기

아옳옳의 코딩공부/아옳옳의 안드로이드스튜디오

2021-05-4안드로이드 스튜디오(Thread )

반응형

안드로이드에서는 메인쓰레드는 UI동시접근을 막는다 ( 그래서 다른 쓰레드에서 직접 접근이 안된다 ) 

 

그래서아래의 그림처럼 핸들러를 통하여 받아서 사용을 할 수 있다.  

여기서 중요한 내용은 뒤에서 배우겠지만 메세지큐에서 핸들러로 보낼때 루퍼라는 것이 있다. 

거기에서 루퍼는 메시지큐에 어떠한 데이터가 들어오는지 대기하다가 데이터가 들어오면 핸들러에 알려준다

(나중에 배움) 

public class MainActivity extends AppCompatActivity {


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

        textView=findViewById(R.id.textView);

    }

    public void onThread(View view) {
        MyThread thread = new MyThread();
        thread.start();
    }
    class MyThread extends Thread{
        public void run(){
            for(int i = 0 ; i<100 ; i++){
                String str = "#"+i+"호출됨";
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                textView.setText(str);
            }

        }
    }

}

이런 오류가 뜬다 오류가 뜨는 이유는 다른 쓰레드에서 직접 접근을 할려고 하다보니 아래의 오류가 뜨는데 

그래서 로그로 해보면 로그로는 작동이 잘 되는것을 볼수 있다. 

 

그럼 위에서 배운 내용처럼 핸들러를 통해서 작업을 한 코드를 보자 

public class MainActivity extends AppCompatActivity {

    MyHandler handler = new MyHandler();
    TextView textView;
    Handler handler2 = new Handler();

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

        textView = findViewById(R.id.textView);

    }

    public void onThread(View view) {
        MyThread thread = new MyThread();
        thread.start();
    }

    class MyThread extends Thread {
        public void run() {
            for (int i = 0; i < 100; i++) {
                String str = "#" + i + "호출됨";
//                여러개의 데이터를 보낼때 사용되는 정석적인 방법
//                Message message = handler.obtainMessage();
//                Bundle bundle = new Bundle();
//                bundle.putString("data", str);
//                message.setData(bundle);
//                handler.sendMessage(message);

//
//               간단한거 보낼때 이렇게 간단하게 사용가능하다
//               handler.sendEmptyMessage(i);
//               handler.sendEmptyMessageDelayed(i,5000);  // 딜레이주고 보낼때
                
        // 핸들러 없이 직접 사용하는 방법 
                handler2.post(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(str);
                    }
                });

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //Log.d("Mythread",str);

            }

        }
    }

    class MyHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
//            여러개의 데이터를 보낼때 사용하는 방법
//            Bundle bundle = msg.getData();
//            String str = bundle.getString("data");
//            textView.setText(str);

            textView.setText("#" + msg.what + "호출됨");
        }
    }

}

  총3가지 방법으로 해보았다 정석적으로 메세지에 담아서 보내주는법과 , 간단한데이터를 보낼때 사용하는법,  post로 직접 사용하는 법 이렇게 3가지 있는데 그림과 코드를 보면 이해가 어렵지 않다. 

 

그럼 이걸 사용하여 실습겸 문제를 해보자~

public class MainActivity extends AppCompatActivity {

    TextView textView;
    MyHandler handler = new MyHandler();
    Boolean run = false;
    Boolean loop = true;
    Boolean first = true;
    MyThread thread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.main_textView);

        thread = new MyThread();
    }

    public void pauseView(View view)  {
           run = false;
    }
    //스타트 버튼을 눌럿을때 처음인지 아닌지에따라 처음이라면 스레드 시작 
    public void startView(View view) {
        if (first) {
            run = true;
            first = false;
            thread.start();
        }else {
            run = true;
        }
    }

    class MyThread extends Thread {
        public void run() {
            //무한루프를 돌면서 순차적으로 실행하다 카운트가 0이되면 
            //피니쉬라는 글자를 보내면서 루프 탈출 
            try {
                int count = 10;
                while (loop) {
                    if(run) {
                        count--;
                        Thread.sleep(1000);
                        Message message = handler.obtainMessage();
                        message.what = 1 ;
                        message.arg1 = count;
                        handler.sendMessage(message);
                        if(count == 0 ){
                            message = new Message();
                            message.what = 2;
                            message.obj = "finish!!";
                            handler.sendMessage(message);
                            loop = false;
                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //받은 메세지들이 어떤것인지에 따라 0~10 을 출력하다 마지막에 받은 finㅑsh 출력
    class MyHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            if (msg.what == 1){
                textView.setText(String.valueOf(msg.arg1));
            }else if (msg.what == 2){
                textView.setText((String)msg.obj);
            }
        }
    }
}

반응형