如何用Service来启动背景音乐

概述:

    其实一开始我也不没有认真想过当我们在我们的Android程序中添加背景音乐时,这项功能应该怎么实现。只是傻乎乎地在Activity中添加这项功能,并且并不认为自己这样写会有什么问题。


思路分析:

    可是,我们是否想过这样一个问题:如果我们添加的音乐播放器的这个Activity异常关闭或是我们人为关闭时,我们的音乐播放还是否能够继续呢?

    答案肯定是不能的。我们的Activity都关闭了,那基于这个Activity的功能又怎么可能还能继续呢?那你可能会问:那我们应该怎么去实现这个功能呢?有人可能会想到,那我就去重新new一个线程,不就好了吗?我只能说这个想法很好,不过这个是行不通的。原因可能是你现在new的这个线程是作为UI线程一个子线程,当父线程都停止工作了,子线程又怎么还会苟活!

    其实,我们不要忘了,Android的四大组件中,有一个Service。它的功能类似于Activity,只是Service是在后台工作,不出现在用户的视野中。当我们在前台上进行一个人机交互操作,让这个操作关联到Service上,这样,我们就能够解决之前我们遇到的那个问题了。

    Service中也有一个onCreate()的回调方法,当我们的Service被创建时就会回调这个方法。我们可以在Service被创建时,启动背景音乐。Service中也有一个onDestroy()的回调方法,当我们的Service被关闭之前会回调这个方法。这样,我们就可以在onDestroy()这个方法里,写关闭背景音乐的代码。下面我给出这个程序的前台和后台的关键代码。


前台程序:

public class MusicActivity extends Activity
{
	Button open, close, getTime;
	// 保持所启动的Service的IBinder对象
	MusicService.MyBinder binder;
	// 定义一个ServiceConnection对象
	private ServiceConnection conn = new ServiceConnection()
	{
		// 当该Activity与Service连接成功时回调该方法
		@Override
		public void onServiceConnected(ComponentName name
			, IBinder service)
		{
			System.out.println("--Service Connected--");
			// 获取Service的onBind方法所返回的MyBinder对象
			binder = (MusicService.MyBinder) service;
		}

		// 当该Activity与Service断开连接时回调该方法
		@Override
		public void onServiceDisconnected(ComponentName name)
		{
			System.out.println("--Service Disconnected--");
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获取程序界面中的start、stop、<span style="font-family: Arial, Helvetica, sans-serif;">getTime</span><span style="font-family: Arial, Helvetica, sans-serif;">按钮</span>
		open = (Button) findViewById(R.id.bind);
		close = (Button) findViewById(R.id.unbind);
		getTime = (Button) findViewById(R.id.getServiceStatus);
		// 创建启动Service的Intent
		final Intent intent = new Intent();
		// 为Intent设置Action属性
		intent.setAction("com.music.service.BIND_SERVICE");
		open.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 绑定指定Serivce
				bindService(intent, conn, Service.BIND_AUTO_CREATE);
			}
		});
		close.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 解除绑定Serivce
				unbindService(conn);
			}
		});
		getTime.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 获取、并显示Service的count值
				Toast.makeText(MusicActivity.this,
					"Serivce的count值为:" + binder.getCount(),
					Toast.LENGTH_SHORT).show(); //②
			}
		});
	}
}


后台程序:

public class MusicService extends Service
{
	private int count;
	private boolean close;
	MediaPlayer m_PlayMid = null;
	// 定义onBinder方法所返回的对象
	private MyBinder binder = new MyBinder();
	// 通过继承Binder来实现IBinder类
	public class MyBinder extends Binder //①
	{
		public int getCount()
		{
			// 获取Service的运行状态:count
			return count;
		}
	}
	// 必须实现的方法,绑定该Service时回调该方法
	@Override
	public IBinder onBind(Intent intent)
	{
		System.out.println("Service is Binded");
		// 返回IBinder对象
		return binder;
	}
	// Service被创建时回调该方法。
	@Override
	public void onCreate()
	{
		super.onCreate();
		System.out.println("Service is Created");
		m_PlayMid = MediaPlayer.create(this, R.raw.just_the_way_you_are);
		m_PlayMid.setLooping(true);
		// 启动一条线程、动态地修改count状态值
		new Thread()
		{
			@Override
			public void run()
			{
				while (!close)
				{
					try
					{
						Thread.sleep(1000);
					}
					catch (InterruptedException e)
					{
					}
					count++;
					m_PlayMid.start();
				}
			}
		}.start();
	}
	// Service被断开连接时回调该方法
	@Override
	public boolean onUnbind(Intent intent)
	{
		System.out.println("Service is Unbinded");
		return true;
	}
	// Service被关闭之前回调该方法。
	@Override
	public void onDestroy()
	{
		super.onDestroy();
		this.close = true;
		m_PlayMid.stop();
		System.out.println("Service is Destroyed");
	}
}


源代码分享:

下面是我的Demo源码地址:用Service来启动背景音乐


原文地址:https://www.cnblogs.com/fengju/p/6336159.html