2012. 8. 3. 22:56

[출처 :http://blog.naver.com/khs7515?Redirect=Log&logNo=20155866934 ] 




Service란 액티비티와는 반대로 눈에 보이지 않는 작업 단위를 처리하는 객체이다.

   Thread와 다른점은 Thread는 Activity와 생명주기를 함께 하지만 Service는 스스로의 생명주기를 가지고 있기 때문에

   따로 종료해주지 않는 이상 앱을 종료해도 살아있다.


# 본 예제는 시작 버튼을 누르면 서비스를 상속받은 페이지로 이동해서 Thread를 실행시키고 Thread가 10초 단위로 5개의 메세지를 

   순서대로 handler에 보낸다. handler는 받은 메세지를 Notification(알림)을 통해서 출력한다.


*************************************** MainActivity.java ******************************************


package test.day10.service;


/*

 * [ 안드로이드 4대요소 ]

 *  

 * 1. Activity - 실체 사용자를 대면하고 입력을 받는 것

 * 2. Service - 레이아웃이 없는데 뭔가 작업한다. 감시를 한다던가..(manifest등록해야한다)

 * 3. Alarm 

 * 4. ContentProvider - 콘텐츠 공급 객체(다른 어플의 자원, 사진, 동영상, 음악을 읽어올때)

 * 

 */

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;


public class MainActivity extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

    }

    //서비스 시작 시키기

    public void start(View v){

     //인텐트 객체 생성

     Intent intent = new Intent(this, MyService.class);

     //서비스 시작시키기

     startService(intent);

    

    }

    //서비스 종료 시키기

    public void end(View v){

     //인텐트 객체 생성

     Intent intent = new Intent(this, MyService.class);

     //서비스 종료시키기

     stopService(intent);

    }

}


*************************************** MyService.java ******************************************


package test.day10.service;



import android.app.Notification;

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.app.Service;

import android.content.Context;

import android.content.Intent;

import android.os.Handler;

import android.os.IBinder;

import android.os.Message;

import android.widget.Toast;

//manifest에 등록해야함.

public class MyService extends Service{


//알림을 띄울 것이므로 

NotificationManager notiManager;

//thread

ServiceThread thread;

//알림을 중복을 피하기 위한 상태값

final int MyNoti = 0;

@Override

public IBinder onBind(Intent intent) {

//할일 없음

return null;

}

//서비스가 시작되면 onstartcommand가 호출된다. 

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

/*

 * 서비스에서 수행할 작업을 수행시키고 재빨리 리턴한다.

 * 시간이 오래 걸리면 서비스가 취소된다.

 * 액티비티는 생명주기가 있지만 서비스는 생명주기가 없다(메모리가 부족하지 않다면 계속 백그라운드에 떠있다.)

 * ex. 카카오톡의 경우 새로운 메시지가 오는지 지속적으로 관찰하는 작업

 */

notiManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

//백그라운드에서 작업할 내용을 초기화 하고 시작한다.

thread = new ServiceThread(handler);

//스레드 시작하기

thread.start();

return START_STICKY;

}

//서비스가 종료될 때 할 작업

public void onDestroy() {

//스레드 종료시키기

thread.stopForever();

thread=null;//쓰레기 값을 만들어서 빠르게 회수하라고 null을 넣어줌.

}

//백그라운드 스레드로부터 메세지를 받을 핸들러 객체 

Handler handler = new Handler(){

public void handleMessage(android.os.Message msg) {

//what으로 메시지를 보고 obj로 메시지를 받는다.(형변환필수)

//notification 객체 생성(상단바에 보여질 아이콘, 메세지, 도착시간 정의)

     Notification noti = new Notification(R.drawable.icon//알림창에 띄울 아이콘

     , "메시지 도착!", //간단 메세지

     System.currentTimeMillis()); //도착 시간

     //기본으로 지정된 소리를 내기 위해

     noti.defaults = Notification.DEFAULT_SOUND;

     //알림 소리를 한번만 내도록

     noti.flags = Notification.FLAG_ONLY_ALERT_ONCE;

     //확인하면 자동으로 알림이 제거 되도록

     noti.flags = Notification.FLAG_AUTO_CANCEL;

     //사용자가 알람을 확인하고 클릭했을때 새로운 액티비티를 시작할 인텐트 객체

     Intent intent = new Intent(MyService.this, MainActivity.class);

     //새로운 태스크(Task) 상에서 실행되도록(보통은 태스크1에 쌓이지만 태스크2를 만들어서 전혀 다른 실행으로 관리한다)

     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

     //인텐트 객체를 포장해서 전달할 인텐트 전달자 객체

     PendingIntent pendingI = PendingIntent.getActivity(MyService.this, 0, intent, 0);

     //받아온 메시지 담기

     String arrivedMsg = (String)msg.obj;

     //상단바를 드래그 했을때 보여질 내용 정의하기

     noti.setLatestEventInfo(MyService.this, "[새 메세지]", arrivedMsg, pendingI);

     //알림창 띄우기(알림이 여러개일수도 있으니 알림을 구별할 상수값, 여러개라면 상수값을 달리 줘야 한다.)

     notiManager.notify(MyNoti, noti);

     //토스트 띄우기

     Toast.makeText(MyService.this, arrivedMsg, 0).show();

    

}

};


}



*************************************** ServiceThread.java ******************************************


package test.day10.service;


import android.os.Handler;

import android.os.Message;

/*

 * 서비스에서 사용할 스레드 클래스

 */

public class ServiceThread extends Thread{

//서비스 객체의 핸들러

Handler handler;

boolean isRun = true;

//예제로 서비스할 메세지

String msg[] = {"나는 서비스 입니다.", "액티비티와 상관없이 살아있습니다.", "메세지1", "메세지2", "메세지3"};

//생성자

public ServiceThread(Handler handler){

this.handler = handler;

}

//스레드 정지 시키는 메소드

public void stopForever(){

synchronized (this) {

this.isRun = false;

notify();

}

}

int index;

//스레드 본체

public void run(){

//반복적으로 수행할 작업을 한다.

while(isRun){

//핸들러로 들어오는 메시지별로 다르게 동작.

String message = msg[index];

index++;

//핸들러에 전달할 Message 객체 생성하기

Message m = new Message();

if(index==4) index = 0;

if(index==3) {

m.what = 1;

m.obj = message;

}else{

m.what = 0;

m.obj = message;

}

//핸들러에 메세지를 보낸다.

handler.sendMessage(m);

try{

Thread.sleep(10000); //10초씩 쉰다.

}catch (Exception e) {}

}

}

}



*************************************** main.xml ******************************************


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

<TextView  

    android:layout_width="fill_parent" 

    android:layout_height="wrap_content" 

    android:text="서비스 테스트"

    />

    <Button android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:text="서비스 시작"

    android:onClick="start"/>

    <Button android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:text="서비스 종료"

    android:onClick="end"/>

</LinearLayout>



*************************************** AndroidManifest.xml ******************************************



<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="test.day10.service"

      android:versionCode="1"

      android:versionName="1.0">

    <uses-sdk android:minSdkVersion="8" />


    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <activity android:name=".MainActivity"

                  android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

<service android:name=".MyServiceandroid:enabled="true"/>

    </application>

</manifest>

Posted by k1rha