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() 메서드는 서비스의 생성과 소멸할 때 자동 호출되는 메서드이며 한번만 실행된다.
서비스 메서드에서,
화면이 없는 서비스에서 화면이 있는 액티비티를 띄울 때는 태스크(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/
'Android' 카테고리의 다른 글
워험권한 (Dangerous Permission) (0) | 2018.05.28 |
---|---|
Broadcast Receiver (브로드캐스트 수신자) (0) | 2018.05.26 |
액티비티 수명주기 (Activity Lifecycle) - (2) (0) | 2018.05.19 |
액티비티 수명주기 (Activity Lifecycle) - (1) (0) | 2018.05.19 |
부가데이터 (Extra) - Serializable & Parcelable (0) | 2018.05.19 |