안드로이드 19일차

ParkJinYoung·2022년 11월 4일
0

스레드(Thread)

  • 병렬프로세싱 : 둘 이상의 작업을 동시에 처리
  • Yield : 양보하기 , interrupt : 끼어들기
  • start => run => destroy






    -MainTread 와 SubTread사이에 Handler(Message) 필요

스톱워치

public class Fragment_2 extends Fragment {

    TextView tv_count1;
    TextView tv_count2;
    Button btn_1;
    Button btn_2;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_2, container, false);
        tv_count1 = view.findViewById(R.id.tv_count1);
        tv_count2 =view.findViewById(R.id.tv_count2);
        btn_1 =view.findViewById(R.id.btn_1);
        btn_2 =view.findViewById(R.id.btn_2);

        // 1. Thread 는 클래스로 설계 해놓고 객체 생성해서 실행시킨다
        // 2. Thread 는 절대 스스로 무한반복하지 않는다
        btn_1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                timeThread th = new timeThread(tv_count1); //
                th.start();
            }
        });
        btn_2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                timeThread th = new timeThread(tv_count2); //
                th.start();
            }
        });


        return view;
    }

    // Handler 설계 (Message)
    Handler handler = new Handler(){
        // MainThread에 메세지 전송 (SubThread한테 요청받아서)


        @Override //일반클래스
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            //SubThread가 메세지 보내면 받아서 처리하는 메소드
            // 상위로 보내기 위해 super
            // ✔✔✔ TextView에 숫자적기
            TextView tv = (TextView) msg.obj;
            tv.setText(msg.arg1+"");
        }
    };

    // 보통 Thread는 따로 java 파일 생성해서 설계하기도 하지만
    // Android에서는 java파일을 많이 생성하면 헷갈릴 수 있어서 InnerClass로 설계한다.

    class timeThread extends Thread{
        // Runnable 라는 인터페이스를 구현(implements) 해서 설계하는 방법도 있다.
        
        // 생성자 객체 생성할 때 결정됨
        private TextView tv_count; // 이 Thread가 숫자를 적어야하는 TextView
        // 추상적으로 설계해서 유연하게 만든다 , 객체 생성시 결정
        // => 생성자 메소드

        public timeThread(TextView tv_count){
            this.tv_count = tv_count;
        }

        @Override
        public void run() {
            // start() => run() => destroy()
            // 1. start() 메소드는 Thread를 시작할 때 호출한다 ✔이 메소드 내에서 run()을 호출한다.
            // 시작하기 위한 모든 준비를 한다. run() 딱 한번 호출


            for(int i = 10; i>0;i--){
                Message msg = new Message(); // Handler에게 보낼 메세지
                msg.obj = tv_count; // 어디에 써야할지 (공간)
                msg.arg1 = i;//뭐라고 쓸건지 (내용)

                handler.sendMessage(msg);
                // 1초쉬기
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

두더지잡기

public class Fragment_3 extends Fragment {
    ImageView[] imgs = new ImageView[9];
    TextView tv_score;
    TextView tv_time;
    int[] OnOff= new int[]{R.drawable.on,R.drawable.off};
    private int cnt = 0;
    final String[] tags = {"on","off"};

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_3, container, false);

        tv_score = view.findViewById(R.id.tv_score);
        tv_time = view.findViewById(R.id.tv_time);

        for(int i = 0;i<imgs.length;i++){
            int resId = getResources().getIdentifier("img_0"+(i+1),"id",
                    getActivity().getPackageName());
            imgs[i] = view.findViewById(resId);
            imgs[i].setImageResource(R.drawable.off);
            //new DoThread(imgs[i]).start()
            DoThread dt = new DoThread(imgs[i]);
            dt.start();


            imgs[i].setTag("off");
            imgs[i].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 두더지 클릭했을때
                    // 현재 이미지뷰에 set 되어있는 리소스 가지고오는 기능 X
                    // View에 태그를 달아서 구분하는 방법

                    if(view.getTag().toString().equals("on")){
                        // 올라온 상태 두더지
                        cnt++;

                    }else{
                        cnt--;
                    }
                    tv_score.setText(cnt+"");
                }
            });
        }

        return view;
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            //((ImageView)(msg.obj)).setImageResource(msg.arg1)
            ImageView imageView = (ImageView) msg.obj;
            imageView.setImageResource(msg.arg1);

            ((ImageView) msg.obj).setTag(tags[msg.arg2]);
        }
    };

    // 두더지 움직이는 Thread 설계
    // 일반클래스
    class DoThread extends Thread{
        // 클래스가 하는일 :
        // ImageView 전달(생성자)받아서 on이미지 리소스(int)/off(int)로 바꿔줌
        // => 랜덤으로 바뀜
        private ImageView dodo; //담당두더지

        public DoThread(ImageView dodo){
            this.dodo = dodo; // 생성자는 리턴타입없음, 이름같음
        }

        @Override
        public void run() {

            while(true){
                int OffTime = new Random().nextInt(5000)+500; //0.5 ~ 5.5초 사이

                try {
                    Thread.sleep(OffTime);
                    // OffTime만큼 쉰뒤 이미지 on으로 바꾼다.
                    // SubThread여서 이미지 바꾸는게 불가능
                    // Handler한테 요청해야함

                    Message msg = new Message();
                    msg.obj = dodo;
                    msg.arg1 = R.drawable.on;
                    msg.arg2 = 0; // 태그도 on으로 바꿔주기
                    handler.sendMessage(msg);

                    //올라와있는 상태에서 조금기다리기
                    int OnTime = new Random().nextInt(1000)+500;//0.5 ~ 1.5초 사이
                    Thread.sleep(OnTime);

                    // off로 바꿔달라고 Handler한테 요청하기
                    // 한 번 전송한 Message는 재사용 할 수 없음
                    msg = new Message();
                    msg.obj = dodo;
                    msg.arg1 = R.drawable.off;
                    msg.arg2 = 1; // 태그도 off로 바꿔주기
                    handler.sendMessage(msg);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}
profile
꾸준히

0개의 댓글