◎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"?>
xmlns:app="http://schemas.android.com/apk/res-auto"
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
|
package com.lcw.ex63servicetest;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
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();
}
}
public void clickStop(View view) {
//백그라운드 작업 종료
}
//백그라운드 작업을 하는 스레드
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();}
}
}
}
}
|
멈추지 않는 이유는 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
|
package com.lcw.ex63servicetest;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;
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
|
package com.lcw.ex63servicetest;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
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);
}
}
|
'안드로이드 웹앱 콘테츠 개발자 양성(국비지원) > Android 기능' 카테고리의 다른 글
Android Studio(기능) Location / Map 각 사이트 이용 방법 (0) | 2019.10.11 |
---|---|
Android Studio(기능) LBS 3 (지도 앱에 해당 위치 표시하기) (0) | 2019.10.10 |
Android Studio(기능) LBS 2(Location Test) (0) | 2019.10.10 |
Android Studio(기능) LBS(Location Test) (0) | 2019.10.10 |
Android Studio(기능) Service 2 (Background 작업) 음악재생 (0) | 2019.10.08 |
댓글