본문 바로가기
안드로이드 웹앱 콘테츠 개발자 양성(국비지원)/Android 기능

Android Studio(기능) Service

by 차누감 2019. 10. 8.
반응형

◎4대 주요 구성요소 [면접때 물어보기도 합니다.]

1) Activity - 화면 담당

2) Service - 백그라운드 작업

3) Broadcast Receiver - 디바이스 상태 정보 사용

4) Content Provider - 다른 앱에 Data 제공

 

살짝 라이프 사이클을 말하면,

MainActivity-MainThread는 화면에 보일 때만 실행되고, 화면이 안보일 때 정지한다.

그리고 화면(Activity)마다 MainThread가 있다.

 

카톡 같은걸 보면 앱을 꺼도 메세지가 온다.( 그러면 MainThread가 실행하는게 아닌걸 알 수 있다.)

화면에 안보여도 실행하는 것이 필요한데 이게 바로 Service( 화면이 없을때 동작[백그라운드 작업] )다.

 

그리고  Activity (StartActivity), Service (StartService), Broadcast Receiver (sendBroadcast)3개는

Intent가 필요하고, Manifest에 등록을 하고, 상속을 받는다.

 

Thread를 만들어도 Back Ground 작업을 할 수 있다. 

왜 그럼 Service를 만들었는지 알아보자. (예제에서는 Thread만 사용했을때 문제점을 보겠다.)

 

예제는 버튼을 누르면 Thread가 백그라운드 작업을 하게 해보자.

START 버튼을 누르면 만든 Thread가 Toast를 띄운다.

STOP 버튼을 누르면 Thread의 반복문 조건 값을 false로 바꿔서 종료한다.

activity_main.xml 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">
 
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="START"
        android:onClick="clickStart"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="STOP"
        android:onClick="clickStop"/>
 
 
 
</LinearLayout>
 
 

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 
 
 
public class MainActivity extends AppCompatActivity {
 
    MyThread thread;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    public void clickStart(View view) {
        //백그라운드 작업 시작
        if(thread==null) {
            thread=new MyThread();
            thread.start();
        }
    }
 
    public void clickStop(View view) {
       //백그라운드 작업 종료
        if(thread!=nullthread.isRun=false;
    }
 
    //백그라운드 작업을 하는 스레드
    class MyThread extends Thread{
 
        boolean isRun= true;
        @Override
        public void run() {
            while (isRun){
 
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this"aaa", Toast.LENGTH_SHORT).show();
                    }
                });
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {e.printStackTrace();}
 
            }
        }
    }
}
 
 
 

 

 

START를 시키면 Toast가 나오고, 앱을 종료 시켜도 Background에서 실행되는 것을 볼 수 있다. 하지만 종료하려고 앱을 다시 실행시켜서 STOP을 누르지만 멈추지 않는 문제가 생긴다.

 멈추지 않는 이유는 Thread의 참조변수가 MainActivity의 멤버 변수이다. 그래서 앱 화면이 꺼지면 참조변수는 없어지므로 Thread를 제어할 변수가 없어서 제어를 못한다. 이제 Toast는 계속 나올 것이다. 이걸 끄려면 앱을 지우거나, 앱 설정에서 강제 종료 시켜야 한다.

 

이제 Service를 이용해서 똑같이 작동하게 해보자.

(차이점 :앱을 껐다가 다시 앱을 켜서 STOP을 누르면 Toat가 종료된다.)

 

Service 클래스를 먼저 만들자.

 

MyService.java 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 
 
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
 
public class MyService extends Service {
    //서비스를  실행하기 위해 startService()를
    //호출했을 때 자동으로 실행되는 메소드
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
 
        //이 안에서 백그라운드 작업 실행
        //3초마다 토스트 보이기
        Toast.makeText(this"bbb", Toast.LENGTH_SHORT).show();
        handler.sendEmptyMessageDelayed(0,3000);
 
        //서비스객체는 메모리 문제가 발생할 때
        //운영체제에서 임의적으로 kill 하는 경우도 있음.
        //START_STICKY : kill되었다가 다시 메모리 문제가 해결되면 자동 실행되도록 하는 리턴값.
        return START_STICKY;
    }
    //서비스를 종료하기 위해 stopService()를
    //호출하면 자동으로 실행되는 메소드
    @Override
    public void onDestroy() {
        handler.removeMessages(0);
        super.onDestroy();
    }
 
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
 
        return null;
    }
 
    Handler handler= new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            Toast.makeText(MyService.this"bbb", Toast.LENGTH_SHORT).show();
            handler.sendEmptyMessageDelayed(0,3000);
 
        }
    };
 
}
 
 
 

MainActivity.java 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
 
 
public class MainActivity extends AppCompatActivity {
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    public void clickStart(View view) {
        //백그라운드 작업 시작
        //백그라운드 작업 전용 class인 Service를 시작하도록
        Intent intent=new Intent(this,MyService.class);
        startService(intent);
 
    }
 
    public void clickStop(View view) {
       //백그라운드 작업 종료
        Intent intent= new Intent(this, MyService.class);
        stopService(intent);
 
    }
}
 
 
 

 

처음과 달리 앱을 다시 실행 시켜도, 제어가 가능하다!!

반응형

댓글