android开发步步为营之60:IntentService与Service的区别

         这个面试的时候,相信是面试官最爱的问题之一。简单的来说,IntentService继承至Service,Service和Acitivity一样是依附于应用主进程的,它本身不是一个进程或者一个线程。一些耗时的操作可能会引起ANR的bug,(本文测试的时候,Service执行20秒没有报ANR惊讶),而IntentService,看它的源代码,onCreate()其实是创建了一个新的线程。

        

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app;

import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;


public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }


    public IntentService(String name) {
        super();
        mName = name;
    }


    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

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

    protected abstract void onHandleIntent(Intent intent);
}


        Looper对象会每次从MessageQueue中获取Intent对象,然后Handler处理消息,调用void onHandleIntent(Intent intent),在这里可以执行一些耗时的比如下载文件等操作。每次调用IntentService都会生成新的HandlerThread,所以不会阻塞UI主线程。如果需要在一个Service里执行耗时操作,那么IntentService是一个很好的选择,不用在Service里面new Thread()或者New AsyncTask()了那么麻烦了。下面再看看我们本实验的demo,对比Service和IntentService对Acitivity的影响。

       第一步:创建Service和IntentService

package com.figo.study.service;

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

public class TestService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		try {
			Thread.sleep(20000);
			System.out.print("service执行完成");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return super.onStartCommand(intent, flags, startId);
	}

}



/**
 * 
 */
package com.figo.study.service;

import android.app.IntentService;
import android.content.Intent;

/**
 * @author Administrator
 *
 */
public class TestIntentService extends IntentService {

//	public TestIntentService(String name) {
//		// TODO Auto-generated constructor stub
//		super(name);
//	}
	public TestIntentService() {
		super("TestIntentService");
	}

	/* (non-Javadoc)
	 * @see android.app.IntentService#onHandleIntent(android.content.Intent)
	 */
	@Override
	protected void onHandleIntent(Intent intent) {
		// TODO Auto-generated method stub
		try {
			Thread.sleep(20000);
			System.out.print("intentService执行完成");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}


        第二步:AndroidManifest.xml注册Service和Activity


        <service
            android:name="com.figo.study.service.TestService"
            android:exported="false" >
            <intent-filter>
                <action android:name="TestService" />
            </intent-filter>
        </service>

        <service
            android:name="com.figo.study.service.TestIntentService"
            android:exported="false" >
            <intent-filter>
                <action android:name="TestIntentService" />
            </intent-filter>
        </service>
        <activity
            android:name="com.figo.study.IntentServiceActivity"
            android:theme="@android:style/Theme.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

       第三步:创建测试Activity

/**
 * 
 */
package com.figo.study;

import com.figo.study.service.TestIntentService;
import com.figo.study.service.TestService;

import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;

/**
 * @author figo
 * 
 */
public class IntentServiceActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		try {

			setContentView(R.layout.activity_intentservice);
			// 启动一个20秒超时的Service,因为是依附在主线程,可以看到必须等service执行完成之后,页面才会展示出来
			// Intent service=new Intent("TestService");
//			Intent service = new Intent(IntentServiceActivity.this,
//					TestService.class);
//			startService(service);
			// 启动一个20秒超时的IntentService,因为是新建线程,所以页面立刻就展示出来了
//			 Intent intentService=new Intent("TestIntentService");
			 Intent intentService=new
			 Intent(IntentServiceActivity.this,TestIntentService.class);
			 startService(intentService);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值