• 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单独出来了



  • 相关阅读:
    设计模式之适配器模式(Adapter)
    数组中的趣味题(二)
    VSTS 2008 自定义签入代码审查策略
    自定义 Vista 系统下程序运行级别
    全国省份,城市,地区全数据(SQL版与XML版)包括各城市邮编
    LINQ 从数据库读数据生成 XML
    IE 8 Beta 2 初体验 隐藏了的"IE7模式"
    利用宏帮助快速录入代码
    你现在的生活是你n年前决定的
    控制参数个数的几种方式
  • 原文地址:https://www.cnblogs.com/hanyuan/p/2587318.html
Copyright © 2020-2023  润新知