Android 백그라운드 작업 IntentService

10891 단어
특정 작업에 특정 스레드를 지정하지 않는 한 프런트 데스크톱 UI 인터페이스에서 대부분의 작업은 UI Thread라는 특수 스레드에서 수행됩니다.UI 인터페이스에서 시간이 많이 걸리는 일부 작업은 인터페이스의 응답 성능에 영향을 줄 수 있으므로 이러한 문제가 발생할 수 있습니다.UI 인터페이스의 성능 문제는 사용자를 화나게 할 수도 있고 시스템 ANR 오류를 초래할 수도 있습니다.이러한 문제를 피하기 위해서, 안드로이드 프레임워크는 몇 가지 종류를 제공하여, 그 소모된 작업을 백엔드 라인으로 이동해서 실행하는 데 도움을 줍니다.이러한 클래스에서 가장 많이 사용되는 것은 Intent Service입니다.
IntentService는 단일 백그라운드 스레드에서 작업을 수행하는 직접적인 방법을 제공합니다.시간이 많이 걸리는 작업을 처리하고 UI의 응답성에 영향을 주지 않도록 합니다.또한 IntentService는 UI 라이프 사이클의 영향을 받지 않으므로 AsyncTask가 원활하게 작동할 수 있습니다.
그러나 IntentService의 한계는 다음과 같습니다.
  • 은 UI와 직접 상호 작용할 수 없습니다.그가 수행한 결과를 UI에 구현하기 위해서는 결과를 액티비티에 되돌려야 한다.
  • 작업 대기열은 순서대로 실행됩니다. 만약 작업이 Intent Service에서 실행되고 있다면, 이 때 새로운 작업 요청을 보내면, 이 새로운 작업은 이전 작업이 실행될 때까지 기다릴 것입니다.
  • 에서 실행 중인 작업은 중단할 수 없습니다.

  • 이러한 제한 사항이 있지만 대부분의 경우 Intent Service는 간단한 백그라운드 작업을 수행하기에 이상적입니다.
    이 단원에서는 상속된 IntentService를 생성하는 방법을 보여 줍니다.또한 필요한 리셋 방법 onHandleIntent()을 만드는 방법도 보여 준다.마지막으로 manfest 파일에서 이 Intent Service를 정의하는 방법도 설명합니다.
    1) IntentService 생성
    앱에 Intent Service 구성 요소를 만들려면 Intent Service를 계승하고 onHandle Intent () 방법을 다시 쓰는 새로운 클래스를 사용자 정의해야 합니다. 다음과 같습니다.
    public class RSSPullService extends IntentService {
        @Override
        protected void onHandleIntent(Intent workIntent) {
            // Gets data from the incoming Intent
            String dataString = workIntent.getDataString();
            ...
            // Do work here, based on the contents of dataString
            ...
        }
    }
    
    일반 서비스 구성 요소의 다른 콜백(예:
    IntentService에서 onStartCommand()이 자동으로 호출됩니다.IntentService에서는 콜백을 다시 쓰는 것을 방지합니다.
    2) Manifest 파일에 IntentService 정의
    IntentService는 manfest 파일에 해당하는 항목을 추가하여 이 항목 요소의 하위 요소로 다음과 같이 정의해야 한다.
    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name">
        ...
        
        <service
            android:name=".RSSPullService"
            android:exported="false"/>
        ...
    <application/>
    
    android:name 속성은 IntentService의 이름을 나타냅니다. 태그에는 intent Filter가 포함되어 있지 않습니다.IntentService에 작업을 보내는 Activity는 명시적인 Intent를 사용해야 하기 때문에 Filter가 필요하지 않습니다.이것은 또한 같은 앱이나 같은 UserID를 사용하는 다른 구성 요소에서만 이 서비스에 접근할 수 있다는 것을 의미한다.
    이로써 기본적인 Intent 서비스 클래스가 생겼습니다. Intent 대상을 구성하여 작업 요청을 보낼 수 있습니다.이러한 대상을 구성하고 Intent Service에 보내는 방식은 다음 과정에서 설명할 것입니다.
    3) 작업 요청을 생성하여 IntentService로 전송
    작업 요청을 생성하여 IntentService로 보내기 위해먼저 현식 Intent를 만들고 요청 데이터를 intent에 추가한 다음 startService() 방법을 호출하여 작업 요청 데이터를 Intent Service에 보내야 합니다.
    다음은 코드 예입니다.
  • Intent Service를 시작하는 데 사용할 새 명시적 Intent를 생성합니다.
  • /*
     * Creates a new Intent to start the RSSPullService
     * IntentService. Passes a URI in the
     * Intent's "data" field.
     */
    mServiceIntent = new Intent(getActivity(), RSSPullService.class);
    mServiceIntent.setData(Uri.parse(dataUrl));
    
  • 실행 startService()
  • // Starts the IntentService
    getActivity().startService(mServiceIntent);
    

    Activity나 Fragment의 어느 곳에서든 작업 요청을 보낼 수 있음을 주의하십시오.예를 들어 사용자 입력을 먼저 가져오면 응답 단추를 누르거나 손짓과 같은 리셋 방법으로 작업 요청을 보낼 수 있습니다.
    start 서비스 () 를 실행하면 Intent 서비스는 자신의 onHandleIntent() 방법에서 이 작업을 시작합니다. 작업이 끝난 후에 이 서비스를 자동으로 정지합니다.
    IntentService를 사용하여 작업 상태 보내기
    IntentService에서 다른 구성 요소에 작업 상태를 보내기 위해 먼저 Intent를 만들고 데이터 필드에 전달해야 할 정보를 포함합니다.옵션으로 이 Intent에 action과 데이터 URI를 추가할 수도 있습니다.
    다음 단계에서는 LocalBroadcastManager.sendBroadcast()을 실행하여 Intent를 보냅니다.Intent는 등록된 어셈블리로 전송됩니다.LocalBroadcastManager의 인스턴스를 가져오려면 getInstance()를 수행합니다.코드의 예는 다음과 같습니다.
    public final class Constants {
        ...
        // Defines a custom Intent action
        public static final String BROADCAST_ACTION =
            "com.example.android.threadsample.BROADCAST";
        ...
        // Defines the key for the status "extra" in an Intent
        public static final String EXTENDED_DATA_STATUS =
            "com.example.android.threadsample.STATUS";
        ...
    }
    public class RSSPullService extends IntentService {
    ...
        /*
         * Creates a new Intent containing a Uri object
         * BROADCAST_ACTION is a custom Intent action
         */
        Intent localIntent =
                new Intent(Constants.BROADCAST_ACTION)
                // Puts the status into the Intent
                .putExtra(Constants.EXTENDED_DATA_STATUS, status);
        // Broadcasts the Intent to receivers in this app.
        LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
    ...
    }
    

    다음 단계는 작업을 보내는 구성 요소에서 보내진broadcast 데이터를 수신합니다.
    4) IntentService로부터 상태 브로드캐스트 수신
    방송의 데이터 대상을 받아들이기 위해서는 BroadcastReceiver의 하위 클래스를 사용하고 BroadcastReceiver.onReceive()을 실현하는 방법이 필요합니다. 여기서 LocalBroadcastManager가 보낸 방송 데이터를 수신할 수 있습니다.
    // Broadcast receiver for receiving status updates from the IntentService
    private class ResponseReceiver extends BroadcastReceiver
    {
        // Prevents instantiation
        private DownloadStateReceiver() {
        }
        // Called when the BroadcastReceiver gets an Intent it's registered to receive
        @
        public void onReceive(Context context, Intent intent) {
    ...
            /*
             * Handle Intents here.
             */
    ...
        }
    }
    

    BroadcastReceiver가 정의되면 actions,categories, 데이터도 필터로 방송해야 합니다.이러한 작업을 수행하려면 IntentFilter가 필요합니다.다음과 같습니다.
    // Class that displays photos
    public class DisplayActivity extends FragmentActivity {
        ...
        public void onCreate(Bundle stateBundle) {
            ...
            super.onCreate(stateBundle);
            ...
            // The filter's action is BROADCAST_ACTION
            IntentFilter mStatusIntentFilter = new IntentFilter(
                    Constants.BROADCAST_ACTION);
    
            // Adds a data filter for the HTTP scheme
            mStatusIntentFilter.addDataScheme("http");
            ...
    

    시스템에 이 BroadcastReceiver와 IntentFilter를 등록하기 위해서는 LocalBroadcastManager를 통해registerReceiver () 를 실행하는 방법이 필요합니다.다음과 같습니다.
    // Instantiates a new DownloadStateReceiver
    DownloadStateReceiver mDownloadStateReceiver =
            new DownloadStateReceiver();
    // Registers the DownloadStateReceiver and its intent filters
    LocalBroadcastManager.getInstance(this).registerReceiver(
            mDownloadStateReceiver,
            mStatusIntentFilter);
    ...
    

    BroadcastReceiver는 여러 유형의 브로드캐스트 데이터를 처리할 수 있습니다.각 브로드캐스트 데이터에는 고유의 ACTION이 있습니다.이 기능은 여러 개의 서로 다른 BroadcastReceiver를 정의하지 않고 서로 다른 ACTION 데이터를 처리할 수 있게 한다.BroadcastReceiver에 대한 다른 IntentFilter를 정의하려면 새 IntentFilter를 만들고 RegisterReceiver () 를 반복해서 실행하면 됩니다.예를 들면 다음과 같습니다.
    /*
     * Instantiates a new action filter.
     * No data filter is needed.
     */
    statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE);
    ...
    // Registers the receiver with the new filter
    LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
            mDownloadStateReceiver,
            mIntentFilter);
    

    브로드캐스트 Intent를 보내도 Activity가 시작되거나 다시 시작되지 않습니다.당신의 앱이 백엔드에서 실행되더라도Activity의BroadcastReceiver는 Intent 대상을 수신하고 처리할 수 있습니다.하지만 이것은 당신의 앱을 무대에 오르게 하지는 않을 것입니다.앱이 보이지 않을 때 백엔드에서 발생하는 이벤트를 알려주려면 Notification을 사용하십시오.라디오 Intent에 응답하기 위해 Activity를 시작하지 마십시오.
    대단히 감사합니다http://developer.android.com/training/run-background-service/index.html

    좋은 웹페이지 즐겨찾기