Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android에서 특정 IntentService를 중지하는 방법

Android에서 특정 IntentService 중지하기

예제를 살펴보기 전에 Android에서 IntentService가 무엇인지 먼저 알아보겠습니다. IntentService는 백그라운드 작업을 비동기적으로 처리하는 서비스입니다. 액티비티에서 startService()를 호출하면 요청마다 새 인스턴스를 생성하지 않고, 서비스 클래스 내에서 작업이 완료되면 자동으로 종료됩니다. 만약 작업이 끝난 후에도 계속 실행되어야 한다면 stopSelf() 메서드를 사용해 수동으로 서비스를 중지할 수 있습니다.

이 예제는 Android에서 특정 IntentService를 중지하는 방법을 보여줍니다.

1단계 — 프로젝트 생성

Android Studio에서 File → New Project로 이동하여 필요한 모든 세부 정보를 입력하고 새 프로젝트를 생성합니다.

2단계 — 레이아웃 파일 작성

res/layout/activity_main.xml에 다음 코드를 추가합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android = "https://schemas.android.com/apk/res/android"
xmlns:app = "https://schemas.android.com/apk/res-auto"
xmlns:tools = "https://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity">
<TextView
android:id = "@+id/text"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "Start Service"
android:textSize = "25sp"
app:layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintLeft_toLeftOf = "parent"
app:layout_constraintRight_toRightOf = "parent"
app:layout_constraintTop_toTopOf = "parent" />
</android.support.constraint.ConstraintLayout>

위 코드에서는 TextView를 하나 배치했습니다. 사용자가 IntentService로부터 데이터를 받으면 이 TextView가 업데이트됩니다.

3단계 — MainActivity 구현

src/MainActivity.java에 다음 코드를 추가합니다.

package com.example.andy.myapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
    TextView text;
    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
       @Override
       public void onReceive(Context context, Intent intent) {
          String s1 = intent.getStringExtra("DATAPASSED");
          text.setText(s1);
       }
   };
   @Override
   protected void onStart() {
      super.onStart();
      IntentFilter intentFilter = new IntentFilter();
      intentFilter.addAction("com.example.andy.myapplication");
      registerReceiver(broadcastReceiver, intentFilter);
   }
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      text = findViewById(R.id.text);
      text.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            startService(new Intent(MainActivity.this, service.class));
         }
      });
   }
   @Override
   protected void onStop() {
      super.onStop();
      unregisterReceiver(broadcastReceiver);
   }
}

위 코드의 핵심은 동적 브로드캐스트 리시버를 생성하고 등록하는 부분입니다. 자세히 살펴보면 다음과 같습니다.

@Override
protected void onStart() {
super.onStart();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.andy.myapplication");
registerReceiver(broadcastReceiver, intentFilter);
}
………
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String s1 = intent.getStringExtra("DATAPASSED");
text.setText(s1);
}
};
………
@Override
protected void onStop() {
super.onStop();
unregisterReceiver(broadcastReceiver);
}

액티비티가 시작되면 onStart()에서 리시버가 등록되고, 종료될 때 onStop()에서 해제됩니다. 리시버는 DATAPASSED라는 키로 전달된 데이터를 받아 TextView에 표시합니다.

서비스 클래스 작성 및 서비스 중지

이제 service.class라는 이름의 클래스 파일을 생성하고 다음 코드를 추가합니다.

package com.example.andy.myapplication;
import android.app.IntentService;
import android.content.Intent;
import android.os.IBinder;
public class service extends IntentService {
    public static volatile boolean shouldStop = false;
    public service() {
       super(service.class.getSimpleName());
    }

    @Override
    public IBinder onBind(Intent intent) {
       return null;
    }

    @Override
    protected void onHandleIntent(Intent intent) {
       Intent intent1 = new Intent();
       intent1.setAction("com.example.andy.myapplication");
       intent1.putExtra("DATAPASSED", "Tutorialspoint.com");
       sendBroadcast(intent1);
       if(shouldStop) {
          stopSelf();
          return;
       }
   }
}

서비스 내부에서는 브로드캐스트를 전송한 후, shouldStop 플래그가 true로 설정되어 있으면 서비스를 종료하도록 처리했습니다. 서비스를 직접 중지하려면 서비스 클래스 내에서 다음 코드를 사용하면 됩니다.

stopSelf();

stopSelf()는 현재 서비스를 안전하게 종료하는 표준적인 방법입니다. volatile 키워드로 선언된 정적 변수 shouldStop을 외부에서 변경함으로써 특정 조건에서 서비스가 스스로 종료되도록 제어할 수 있습니다.

4단계 — 매니페스트 설정

manifest.xml에 다음 코드를 추가합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "https://schemas.android.com/apk/res/android"
    package = "com.example.andy.myapplication">
    <uses-permission android:name = "android.permission.WAKE_LOCK"/>
    <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>
       <service android:name = ".service"/>
    </application>
</manifest>

서비스가 정상적으로 동작하려면 반드시 매니페스트 파일에 <service> 태그로 서비스를 선언해야 합니다. 또한 백그라운드 작업 중 기기가 절전 모드로 전환되지 않도록 WAKE_LOCK 권한을 추가했습니다.

애플리케이션 실행 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 모바일 기기를 컴퓨터에 연결했다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바의 실행(Run) 아이콘을 클릭하세요. 모바일 기기를 선택하면 기기 화면에 아래와 같은 기본 화면이 표시됩니다.

Android에서 특정 IntentService를 중지하는 방법

위 결과는 애플리케이션의 기본 화면입니다. "Start Service" 텍스트를 클릭하면 서비스가 시작되고, 아래 그림과 같이 TextView가 업데이트됩니다.

Android에서 특정 IntentService를 중지하는 방법

서비스가 브로드캐스트를 MainActivity로 전송한 후, IntentService는 stopSelf() 호출을 통해 정상적으로 종료됩니다. 이처럼 stopSelf()와 상태 플래그를 활용하면 원하는 시점에 특정 IntentService를 안전하게 중지할 수 있습니다.