caihanyuan的专栏

向各位前辈高人学习

Service之startServie简单范例

Service的启动方式有两种,一种是用startService()方法启动服务,另一种是用bindService()方法启动服务。startService启动的服务一般不和UI交互,只是在后台运行,后台程序结束后,Service应该关闭。bindService是一种和前台绑定的服务,他可以和UI交互,一个这样的服务可以多个组件绑定,当这些组件都取消和这个服务进行绑定的时候,这个服务会被销毁。

自定义的Service一般都继承Service这个类,并且应该实现这些方法:

1.onStartCommand(): 这个方法是用startService()方法启动时会被调用。

2.onBind(): 这个方法是用bindService()方法启动时被调用. 这个方法一定要实现,如果用startService()启动的服务,那么这个方法返回null即可.

3.onCreate():  第一次生成Service时调用
4.onDestory():  一般用于销毁Service时回收系统资源,停止线程。


下面是用startService()方法启动服务的例子,模仿音乐播放器,在Activity中有三个按钮:"启动服务"、“暂停服务”、“撤销服务”.当点击“启动服务”按钮的时候会调用startService()方法启动服务,“暂停服务”功能还没实现,“撤销服务”会调用stopService()方法撤销服务。当启动服务的时候,Service会启动一个线程,由1计数到100,这个模拟播放进度,并将这个进度值传递到MyMusicPlayer对象中,这个对象是由Activity传递到Service中的。在Activity中也启动一个线程,实时监听MyMusicPlayer的播放进度,达到一定值的时候提示用户.


运行结果:



Service:MyService

public class MyService extends Service
{
	// 播放进度类的引用
	private MyMusicPlayer player;
	private MyPlayerThread playerThread;

	@Override
	public void onCreate()
	{
		System.out.println("Service--->onCreate");
		super.onCreate();
	}

	/**
	 * 当以startService方法启动服务时候,调用这个方法。<br>
	 * 如果是以bindService绑定服务,则可以不用实现这个方法
	 */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		// 得到Activity传来的播放进度类的引用
		if (null == player)
		{
			player = (MyMusicPlayer) intent.getSerializableExtra("Player");
			playerThread = new MyPlayerThread();
			playerThread.setName("thread_in_service");
			playerThread.start();
		}

		System.out.println("Service--->onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}

	/**
	 * 这个方法必须实现,如果是以bindService方法绑定服务,这个要返回指定IBinder<br>
	 * 如果是以startService方法启动服务,则这个方法返回null
	 */
	@Override
	public IBinder onBind(Intent intent)
	{
		System.out.println("Service--->onBind");
		return null;
	}

	@Override
	public void onDestroy()
	{
		System.out.println("Service--->onDestory");
		super.onDestroy();

		if (null != playerThread)
			playerThread.setProgress(100);
	}

	/**
	 * 播放进度线程
	 */
	class MyPlayerThread extends Thread
	{
		// 开始的时候进度为0
		int progress = 0;
		
		public void setProgress(int progress)
		{
			this.progress = progress;
		}

		@Override
		public void run()
		{
			while (progress < 100)
			{
				player.setProgress(progress);
				try
				{
					sleep(1000);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
				progress++;
				System.out.println("Progress is: " + progress);
			}
		}
	}
}
Activity: ServiceDemo

public class ServiceDemo extends Activity
{
	// 播放进度的类的引用,传递到service中,与service交互
	private MyMusicPlayer player;
	// 三个按钮控件的引用
	private Button startButton;
	private Button stopButton;
	private Button destoryButton;
	// 线程控制器
	private Handler handler;
	// 线程
	private ProgressListener progressListener;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		System.out.println("Activity--->onCreate");

		startButton = (Button) findViewById(R.id.start_button);
		stopButton = (Button) findViewById(R.id.stop_button);
		destoryButton = (Button) findViewById(R.id.destory_button);
		// 实例化
		player = new MyMusicPlayer();
		//  处理ProgressListener线程传来的消息
		handler = new Handler()
		{
			public void handleMessage(android.os.Message msg)
			{
				if (ProgressListener.PROGRESS == msg.what)
				{
					System.out.println("当前进度为: " + msg.arg1);
					if (50 == msg.arg1)
						Toast.makeText(ServiceDemo.this, "当前进度为: " + msg.arg1, Toast.LENGTH_LONG).show();
					if(100 <= msg.arg1)
						Toast.makeText(ServiceDemo.this, "已经播放完毕", Toast.LENGTH_LONG).show();
				}
			}
		};
		// 实例化线程
		progressListener = new ProgressListener();

		ServiceStateControl ssc = new ServiceStateControl();
		startButton.setOnClickListener(ssc);
		stopButton.setOnClickListener(ssc);
		destoryButton.setOnClickListener(ssc);
	}

	/**
	 * 三个按钮的监听器,点击后用intent通知service启动、暂停或者关闭
	 */
	class ServiceStateControl implements OnClickListener
	{
		Intent intent = new Intent();

		public void onClick(View v)
		{
			intent.setClass(ServiceDemo.this, MyService.class);
			if (v == startButton)
			{
				// 将MyMusicPlayer引用传递过Service里
				intent.putExtra("Player", player);
				// 启动Service
				startService(intent);
				progressListener.start();
				progressListener.setIsStart(true);
			}
			if (v == stopButton)
			{
				// 暂停服务
			}
			if (v == destoryButton)
			{
				// 撤销Service
				stopService(intent);
				progressListener.setIsStart(false);
			}
		}
	}

	/** 监听播放进度的线程,将进度封装在Message中传递给Handler,让Handler处理 */
	class ProgressListener extends Thread
	{
		// 此线程的编号
		public static final int PROGRESS = 1001;
		// 服务启动状态
		private boolean isStart = false;

		public void setIsStart(boolean isStart)
		{
			this.isStart = isStart;
		}

		@Override
		public void run()
		{
			while (isStart)
			{
				Message message = new Message();
				message.what = ProgressListener.PROGRESS;
				// 传递进度值
				message.arg1 = player.getProgress();
				handler.sendMessage(message);
				try
				{
					sleep(1000);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}

			}
		}
	}
}

传递数据的类:MyMusicPlayer

public class MyMusicPlayer implements Serializable
{
	private static final long serialVersionUID = 1L;
	// 播放进度
	public static int progress;

	public int getProgress()
	{
		return MyMusicPlayer.progress;
	}

	public void setProgress(int progress)
	{
		MyMusicPlayer.progress = progress;
	}
}


这个MyMusicPlayer之前写在ServiceDemo中作为内部类,即使实现了Serializable接口也传递不了,后来意识到MyMusicPlayer作为ServiceDemo的内部类,如果要序列化的话,ServiceDemo里面的所有成员都要序列化,所以把MyMusicPlayer单独出来了



阅读更多
个人分类: Android 技术
上一篇Fragment之Creating event callbacks to activity实例
下一篇简谈GridView
想对作者说点什么? 我来说一句

简单 Windows NT Service范例

2002年09月25日 216KB 下载

没有更多推荐了,返回首页

关闭
关闭