Android开发 Service和IntentService

Service相信大家都很熟悉,一个没有界面的服务,但其实它不是后台的,所有的代码默认在UI线程执行,若要执行耗时操作,需要新开线程或者使用AsyncTask.
IntentService继承自Service,所以,它也是一个服务,但与Service有些区别:
1,Service默认在UI线程执行,而IntentService的onHandleIntent方法在后台执行
2,Service在start后,如果没有手动stop,会一直存在,而IntentService,在执行完后,自动退出.
如果IntentService未执行完上次任务,再次被start,不会再开一个新线程来执行新任务,而是等待之前的任务执行完,再执行新的任务,待所有任务执行完,再stopSelf.
通过查看IntentService的源码,可以发现,其实原理很简单.在OnCreate里创建一个新线程,得到该线程的Looper对象,通过该Looper对象构建一个Handler,在onStart里把Intent当作参数传给该Handler,以实现在OnCreate里创建的线程里运行的目标.在处理完所有任务后, stopSelf(msg.arg1),该msg.arg1就是startId,即每次startService时自动生成的一个唯一id,stopSelf(startId)方法,会判断传入的startId,是不是最后一次调用startService时生成的startId,如果不是,不会关闭服务,是则关闭.即完成最后一次startService的任务后,才关闭Service.

下面是一个小例子:
MainActivity.java;


package com.example.androidtest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

	Button button1,button2;
	Handler threadAHanlder;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button1=(Button)findViewById(R.id.button1);
		button2=(Button)findViewById(R.id.button2);
		
		button1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO 自动生成的方法存根
				Intent intent=new Intent(MainActivity.this,MyService.class);
				startService(intent);
			}
		});
		
		button2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO 自动生成的方法存根
				Intent intent=new Intent(MainActivity.this,MyIntentService.class);
				startService(intent);
			}
		});
	}

}

MyService.java:


package com.example.androidtest;

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

public class MyService extends Service {

	@Override
	public void onCreate() {
		// TODO 自动生成的方法存根
		super.onCreate();
		System.out.println("Service onCreate");
	}
	@Override
	public IBinder onBind(Intent intent) {
		// TODO 自动生成的方法存根
		return null;
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		//在UI线程执行,会阻塞UI,导致ANR
		for(int i=0;i<10;i++)
		{
			System.out.println("Service "+Thread.currentThread().getId()+" "+i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}		
		return super.onStartCommand(intent, flags, startId);
	}
	
	@Override
	public void onDestroy() {
		//没有手动调stopService,不会自己关闭
		super.onDestroy();
		System.out.println("Service Destory");
	}

}

MyIntentService.java:


package com.example.androidtest;

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

public class MyIntentService extends IntentService {

	//没有这个空的构造函数,启动会报错
	public MyIntentService()
	{
		super("aaaa");
	}
	@Override
	public void onCreate() {
		// TODO 自动生成的方法存根
		super.onCreate();
		System.out.println("IntentService onCreate");
	}
	@Override
	protected void onHandleIntent(Intent intent) {
		//若没有执行完,再次start,等待这次执行完后才执行下一次调用,线程id不会变
		for(int i=0;i<10;i++)
		{
			System.out.println("IntentService "+Thread.currentThread().getId()+" "+i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public void onDestroy() {
		//所有任务执行完后,自动关闭
		super.onDestroy();
		System.out.println("IntentService Destory");
	}


}

© 2013, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接! 应用开发笔记

发表评论

电子邮件地址不会被公开。 必填项已用*标注