본문 바로가기
Android

안드로이드 스튜디오, JAVA ] 서비스

by 김마리님 2020. 8. 5.

서비스는 단말이 계속 실행되어 있는 상태로 다른 단말과 데이터를 주고받거나 필요한 기능을 백그라운드에서 실행합니다.

이 때 서비스를 호출하는건 시스템이고, 처음에는 onCreate로 서비스를 생성- 인텐트 전달, 서비스가 켜진 상태로 재호출 되면 다시 onCreate가 되는 것이 아니라, onStartCommand() 매서드를 실행한다.

 

예시 코드를 보자.

 

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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"
    tools:context=".MainActivity">


    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="서비스로 보내기"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Name"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity.java

package com.mary.serviceex01;

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;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText editText;
    private 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 name=editText.getText().toString();

                Intent intent=new Intent(getApplicationContext(),MyService.class);
                intent.putExtra("command","show");
                intent.putExtra("name",name);

                startService(intent);

            }
        });
    }

    }
}

 

메인 페이지에서 이름과, 코멘트를 인텐트를 통하여 서비스에 전달한다.

 

MyService.java

package com.mary.serviceex01;

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

import androidx.annotation.Nullable;

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_NOT_STICKY;
        }else{
            processCommend(intent);
        }
        return super.onStartCommand(intent, flags, startId);
    }


    private void processCommend(Intent intent){
        String command=intent.getStringExtra("command");
        String name=intent.getStringExtra("name");

        Log.d(TAG, "command : "+command+ ", name : "+name);

        for(int i=0;i<5;i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "Waiting : "+i+" seconds.");
        }

    }

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

 

다음과 같이 첫 호출에는 onCreate가 되는것을 볼 수 있고,

 

 

 

두 번째 호출에는 onStartCommand()만 호출되는 것을 볼 수 있다.

 

 

그럼 서비스에서 메인으로 정보를 재호출 하는 형태는 없을까?

 

몇개의 코드를 다시 붙여본다.

 

MyService.java

               e.printStackTrace();
            }
            Log.d(TAG, "Waiting : "+i+" seconds.");
        }

        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("name",name+" From service");
        startActivity(showIntent);

    }

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

인텐트가 종료되면 새 인텐트가 만들어지면서 메인 액티비티로 다시 인텐트를 전달한다.

 

 

MainActivity.java

               intent.putExtra("name",name);

                startService(intent);

            }
        });

        Intent passedIntent=getIntent();
        processIntent(passedIntent);

    }

    @Override
    protected void onNewIntent(Intent intent) {
        processIntent(intent);
        super.onNewIntent(intent);
    }

    private void processIntent(Intent intent){
        if(intent!=null){
            String command=intent.getStringExtra("command");
            String name=intent.getStringExtra("name");

            Toast.makeText(this, "command : "+command+", name : "+name,Toast.LENGTH_LONG).show();

        }
    }
}

메인 액티비티는 인텐트를 받아서 토스트로 값을 호출한다.

 

 

결과 : 

 

보다시피, 서비스가 종료되면 인텐트가 다시 메인으로 돌아오며 토스트가 뜨는 것을 확인할 수 있다.

반응형