나만의 개발노트

[안드로이드] 서비스, startService, onStartCommand 본문

[안드로이드]/[안드로이드] 공부 기록

[안드로이드] 서비스, startService, onStartCommand

노트포미 2023. 10. 13. 13:06
 private void processCommand(Intent intent){
    if(intent != null){

        String string = intent.getStringExtra("Stirng");
        int integer = intent.getIntExtra("Integer",0);

        Log.d("test","From 서비스 : " + string + ", " + integer);
        Toast.makeText(getApplicationContext(),"From 서비스 : " + string + ", " + integer,Toast.LENGTH_LONG).show();
    }
}

서비스

: 화면 없이 백그라운드에서 실행되는 하나의 단위

 

- 애플리케이션의 구성요소이므로 반드시 매니페스트 파일에도 추가해야 함

   *매니페스트에 <Service>태그 

   *우클릭New -> Service로 만들면 자동 입력됨

 

- startService()로 서비스 시작시킴 or 명령이나 데이터를 전달함

- startService에 인텐트 객체를 파라미터로 전달

- 서비스는 백그라운드에서 항상 실행되는 것이므로, 메모리문제로 강제종료 되면 자동 재시작된다

 

[서비스의 메소드]

- onCreate() : 생성될 때

- onDestroy() : 종료될 때

- onStartCommand() : 다른 구성 요소가 서비스를 시작하도록 요청하는 경우

   -> startService가 Intent를 전달하면, 서비스는 onStartCommand()에서 Intent를 받음

 

[사용법1 - 액티비티에서 서비스로의 명령 전달]

1. app -> 우클릭 New -> Service로 서비스 만들기

#기본 MyService.java

package com.example.myservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {
    //생성자
    public MyService() {
    }

    //잘 사용하지 않음
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

2. 우클릭 Generate -> Override Methods... -> onCreate(),onStartCommand(), onDestroy() 오버라이드하기

1) onCreate()

//서비스 가장 처음 시작될 때만 호출됨
@Override
public void onCreate() {
    super.onCreate();

    Log.d("test","onCreate() 호출됨");
}

2) onStartCommand()

//서비스를 호출할 때마다 호출됨 (intent를 전달받는 메소드)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("test","onStartCommand() 호출됨");

    if(intent != null) {
        String string = intent.getStringExtra("String");
        int integer = intent.getIntExtra("Integer",0);
        Log.d("test","전달받은 데이터 : "+string+", "+integer);
    }
    return super.onStartCommand(intent, flags, startId);
}

3) onDestroy()

/서비스가 종료될 때 호출됨
@Override
public void onDestroy() {
    super.onDestroy();

    Log.d("test","onDestroy() 호출됨");
}

 

3. MainActivity에서 Service 호출하기

 

#최종 MyService.java

package com.example.myservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {
    //생성자
    public MyService() {
    }

    //잘 사용하지 않음
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    //서비스 가장 처음 시작될 때만 호출됨
    @Override
    public void onCreate() {
        super.onCreate();

        Log.d("test","onCreate() 호출됨");
    }

    //서비스를 호출할 때마다 호출됨 (intent를 전달받는 메소드)
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("test","onStartCommand() 호출됨");

        if(intent != null) {
            String string = intent.getStringExtra("String");
            int integer = intent.getIntExtra("Integer",0);
            Log.d("test","전달받은 데이터 : "+string+", "+integer);
        }
        return super.onStartCommand(intent, flags, startId);
    }

    //서비스가 종료될 때 호출됨
    @Override
    public void onDestroy() {
        super.onDestroy();

        Log.d("test","onDestroy() 호출됨");
    }
}

#최종 MainActivity.java

package com.example.myservice;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), MyService.class);
                intent.putExtra("String","예시String");
                intent.putExtra("Integer",110);

                startService(intent);
            }
        });
    }
}

 

[실행화면]


[사용법2 - 서비스에서 액티비티로의 명령 전달]

1. MyService.java에 onStartCommand()에 processCommand()호출

2. processCommand() 구성

private void processCommand(Intent intent){
    if(intent != null) {
    	//액티비티 -> 서비스 과정
        String string = intent.getStringExtra("String");
        int integer = intent.getIntExtra("Integer",0);

        Log.d("test","전달받은 데이터 : "+string+", "+integer);
        
        //서비스 -> 액티비티 과정
        try{
            Thread.sleep(5000); //5초 쉬기
        }catch(Exception e){}

		//서비스 -> 액티비티 할 intent 생성
        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("Stirng","show");
        showIntent.putExtra("Integer",123);
        startActivity(showIntent);
    }
}

3. MainActivity.java에 onCreate()에 getIntetnt()추가

Intent passedIntent = getIntent();
processCommand(passedIntent); //processCommand는 전달받은 데이터 표시하는 메소드

4. MainActivity.java에 onNewIntent() 오버라이드 하기

  *이미 액티비티가 생성된 상태일 때, 자동으로 intent 전달받음

protected void onNewIntent(Intent intent) { //MainActivity가 이미 만들어져 있는 상태에서 호출된 경우
    processCommand(intent);

    super.onNewIntent(intent);
}

5. processComand() 만들기

 private void processCommand(Intent intent){
    if(intent != null){

        String string = intent.getStringExtra("Stirng");
        int integer = intent.getIntExtra("Integer",0);

        Log.d("test","From 서비스 : " + string + ", " + integer);
        Toast.makeText(getApplicationContext(),"From 서비스 : " + string + ", " + integer,Toast.LENGTH_LONG).show();
    }
}

최종 MainActivity.java

package com.example.myservice;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), MyService.class);
                intent.putExtra("String","예시String");
                intent.putExtra("Integer",110);

                startService(intent);
            }
        });

        Intent passedIntent = getIntent();
        processCommand(passedIntent);
    }

    @Override
    protected void onNewIntent(Intent intent) { //MainActivity가 이미 만들어져 있는 상태에서 호출된 경우
        processCommand(intent);

        super.onNewIntent(intent);
    }

    private void processCommand(Intent intent){
        if(intent != null){

            String string = intent.getStringExtra("Stirng");
            int integer = intent.getIntExtra("Integer",0);

            Log.d("test","From 서비스 : " + string + ", " + integer);
            Toast.makeText(getApplicationContext(),"From 서비스 : " + string + ", " + integer,Toast.LENGTH_LONG).show();
        }
    }
}

최종 MyService.java

package com.example.myservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {
    //생성자
    public MyService() {
    }

    //잘 사용하지 않음
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    //서비스 가장 처음 시작될 때만 호출됨
    @Override
    public void onCreate() {
        super.onCreate();

        Log.d("test","onCreate() 호출됨");
    }

    //서비스를 호출할 때마다 호출됨 (intent를 전달받는 메소드)
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("test","onStartCommand() 호출됨");

        processCommand(intent);
        return super.onStartCommand(intent, flags, startId);
    }

    private void processCommand(Intent intent){
        if(intent != null) {
            String string = intent.getStringExtra("String");
            int integer = intent.getIntExtra("Integer",0);

            Log.d("test","전달받은 데이터 : "+string+", "+integer);

            try{
                Thread.sleep(5000);
            }catch(Exception e){}

            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("Stirng","show");
            showIntent.putExtra("Integer",123);
            startActivity(showIntent);
        }
    }



    //서비스가 종료될 때 호출됨
    @Override
    public void onDestroy() {
        super.onDestroy();

        Log.d("test","onDestroy() 호출됨");
    }
}

<참조>

https://www.boostcourse.org/mo316/lecture/259035?isDesc=false 

 

안드로이드 앱 프로그래밍

부스트코스 무료 강의

www.boostcourse.org

https://developer.android.com/guide/components/services?hl=ko 

 

서비스 개요  |  Android 개발자  |  Android Developers

서비스 개요 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Service는 백그라운드에서 오래 실행되는 작업을 수행할 수 있는 애플리케이션 구성 요소이며 사

developer.android.com