1. 서비스


화면이 없는 상태에서 백그라운드로 실행된다.

프로세스가 종료되어도 시스템에서 자동으로 재시작한다.



2. 서비스 만들기


App → New → Service → Service 메뉴 클릭

(이렇게 하면, 매니페스트에 자동으로 등록된다.)


AndroidManifest.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
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tistory.qlyh8.pracitice">
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SubActivity" />
 
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>
    </application>
 
</manifest>
cs



서비스를 실행시키기 위해선 인텐트 객체를 파라미터로 전달해야 하며,

인텐트 객체는 시스템으로 전달된 후 시스템에서 지정한 서비스를 만들고 실행한다.



3. Activity → Service 로 인텐트 보내기


서비스 메서드에서,

onCreate(), onDestory() 메서드는 서비스의 생성과 소멸할 때 자동 호출되는 메서드이며 한번만 실행된다.

 
또한, 인텐트 안에 넣어 전달한 명령이나 데이터를 잘 처리할 수 있도록 onStartCommand 메소드를 사용할 수 있다.
onStartCommand 메소드가 호출되면 인텐트 객체를 파라미터로 전달받고 확인할 수 있다.


4. Service → Activity 로 인텐트 보내기


서비스 메서드에서,

화면이 없는 서비스에서 화면이 있는 액티비티를 띄울 때는 태스크(Task)를 새로 만들어 연결한다.

이 때, FLAG_ACTIVITY_NEW_TASK 플래그를 추가하는데 일반적인 경우 세 개의 플래그를 같이 사용한다.

1
2
3
  showIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                      |Intent.FLAG_ACTIVITY_SINGLE_TOP
                      |Intent.FLAG_ACTIVITY_CLEAR_TOP);
cs

액티비티가 화면에 보인 상태에서 startActivity 를 호출하면, 액티비티는 새로 만들어지지 않고 기존 액티비티를 그대로 사용하게 된다.


메인 액티비티에서,

화면에 보이고 있는 액티비티를 그대로 사용하므로 onCreate 메소드가 호출되지 않고, onNewIntent 라는 메소드가 호출된다.

이 메소드가 별도로 호출되는 이유는 인텐트를 전달받기 위한 것이며, onNewIntent 메소드 안에서 인텐트 객체를 확인할 수 있다.



5. 실행 결과 화면


    


6. 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
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.tistory.qlyh8.pracitice;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
 
public class MyService extends Service {
 
    private static final String TAG = "MyService";
 
    public MyService() {}
 
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate() 호출됨");
    }
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand() 호출됨");
 
        if(intent == null) {
            return Service.START_STICKY; // 서비스가 종료되었을 때 다시 자동으로 실행시킨다.
        }
        else{
            //////////////////// 메인 액티비티에 서비스로 인텐트 전달 ///////////////////////
            String command = intent.getStringExtra("command");
            String str = intent.getStringExtra("editStr");
            Log.d(TAG, "인텐트: " + command + " & " + str);
            ////////////////////////////////////////////////////////////////////////////////
 
            /////////////////////// 5초간 쉰 후, 다음 서비스 시작 ///////////////////////////
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ////////////////////////////////////////////////////////////////////////////////
 
            /////////////////// 서비스에서 메인액티비티로 인텐트 보내기 ////////////////////
            Intent showIntent = new Intent(getApplicationContext(), MainActivity.class);
            showIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                                |Intent.FLAG_ACTIVITY_SINGLE_TOP
                                |Intent.FLAG_ACTIVITY_CLEAR_TOP);
            showIntent.putExtra("command""show");
            showIntent.putExtra("editStr", str + "from Service");
            startActivity(showIntent); // 액티비티 시작
            ////////////////////////////////////////////////////////////////////////////////
        }
        return super.onStartCommand(intent, flags, startId);
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy() 호출됨");
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
 
cs



7. 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
55
56
57
58
59
package com.tistory.qlyh8.pracitice;
 
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
 
    EditText editText;
    Button button;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        editText = findViewById(R.id.editText);
        button = findViewById(R.id.button);
 
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String editStr = editText.getText().toString();
 
               // 서비스한테 인텐트 전달
               Intent intent = new Intent(getApplicationContext(), MyService.class);
               intent.putExtra("command""show");
               intent.putExtra("editStr", editStr);
               // 서비스를 실행시키지만, 명령이나 데이터를 전달하기 위한 용도로 사용된다.
               startService(intent);
            }
        });
 
        // 서비스로부터 인텐트 받기
        Intent passedIntent = getIntent();
        processCommand(passedIntent);
    }
 
    // 서비스로부터 받은 인텐트 확인
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        processCommand(intent);
    }
 
    // 서비스로부터 인텐트 전달받기
    public void processCommand(Intent intent){
        if(intent != null){
            String command = intent.getStringExtra("command");
            String str = intent.getStringExtra("editStr");
            Toast.makeText(this"전달받은 데이터: " + command + " & " + str, Toast.LENGTH_LONG).show();
        }
    }
}
 
cs



8. 서비스 확인하기


Tool → Android → Android Device Monitor 를 이용해

Device 탭에서, 실행되고 있는 프로세스를 알 수 있다. 





출처: https://www.edwith.org/boostcourse-android/lecture/17068/

+ Recent posts