Service--服务

Service 

没有用户界面在后台运行执行耗时操作的应用组件,存在于当前进程 的主线程中;

但是一些阻塞UI操作(耗时操作,网络请求,联网操作、数据请求)不能放在service中,需另开启一个线程处理。

启动方式,不同的启动方式对应不同的生命周期

注:他的生命周期中只有onStartCommand 可以执行多次,其他都只执行一次;

1. startServie(intent);

onCreate > onStartCommand >onDestory

2.BindService(intent,ServiceConnection,BIND_AUTO_CREATE);

onCreate > onBind > unOnbind > onDestory


注册

包名+类名

<span style="font-size:14px;"><service android:name="com.scxh.android.service.MusicService" /></span>


实现:

继承Service 

一:通过startService开启服务可以通过intent传参数。

startServie(intent);

二:通过BindService,在onBind中会返回一个IBinder 对象,我们通常在service里写个接口,里面定义方法,再写一个类来实现这个接口,并继承Binder

1.建立一个接口,定义方法

2.定义一个类实现这个接口,并继承Binder

3. 在onBind方法中返回这个接口实例对象;

4.在activity 声明接口,在 new ServiceConnection 里的onServiceConnected方法中将里面的IBinder service 对象强转成接口对象,(当他们建立连接就会得到这个对象)

通过这个接口的实例来实现后台的操作,以播放器为例:

startServie(intent);和BindService 一起在用

服务器端:

package com.scxh.android.service;

import java.io.IOException;
import java.util.ArrayList;

import Constance.MusicBean;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MusicService extends Service {
	MediaPlayer mPlayer;
	// 接口的实例
	MusicServiceBinder musicBinder = new MusicServiceBinder();

	// 数据源 和当前播放位置 是从 activity中通过startService穿过来的
	ArrayList<MusicBean> mListData;
	int currentPosition;

	@Override
	public void onCreate() {
		super.onCreate();

	}

	/*
	 * MediaPlayer 的初始化
	 */
	private void initPlayer() {
		if (mPlayer == null) {
			mPlayer = new MediaPlayer();
		}
		try {
			mPlayer.reset();
			mPlayer.setDataSource(mListData.get(currentPosition).getPath());
			mPlayer.prepare();
			mPlayer.start();

			if (musicBinder != null) {
				musicBinder.changeState();
			}

		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		/*
		 * 一首歌曲播放完以后的方法
		 */
		mPlayer.setOnCompletionListener(new OnCompletionListener() {

			@Override
			public void onCompletion(MediaPlayer mp) {		
				musicBinder.nextMusic();
				mp.start();
			}
		});
	}

	/*
	 * 接收从activity传过来的数据源及position
	 */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		mListData = intent.getParcelableArrayListExtra("musicList");
		currentPosition = intent.getIntExtra("currentPosition", 0);

		initPlayer();
		return super.onStartCommand(intent, flags, startId);
	}

	/*
	 * 返回一个接口的实例
	 */
	@Override
	public IBinder onBind(Intent intent) {
		return musicBinder;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		if (mPlayer != null) {
			mPlayer.stop();
			mPlayer.release();
		}
	}

	/*
	 * 定義的接口
	 */
	public interface MusicBinder {
		// 得到player的播放状态
		public boolean playMusic();

		// 点击下一首
		public int nextMusic();

		// 点击上一首
		public int lastMusic();

		// 得到当前播放的时间
		public int currentTime();

		// 得到当前歌曲的总时间
		public int TotalTime();

		// 当前选中的歌曲播放
		public String seekTo(int position);

		// 得到正在播放歌曲的名字
		public String getCurrentTitle();

		// 拖动进度条,设置他的播放位置
		public void setCurrentTime(int progress);

		// 改变他的播放状态
		public boolean changeState();

	}

	/*
	 * 接口实现类,继承的binder
	 */
	public class MusicServiceBinder extends Binder implements MusicBinder {

		@Override
		public boolean playMusic() {
			if (mPlayer.isPlaying()) {
				mPlayer.pause();
				return false;
			} else {
				mPlayer.start();
				return true;
			}
		}

		@Override
		public int nextMusic() {
			if (++currentPosition > mListData.size() - 1) {
				currentPosition = mListData.size() - 1;
			}
			mPlayer.reset();
			initPlayer();

			sendBroadcast(intent);
			return currentPosition;
		}

		@Override
		public int lastMusic() {
			if (--currentPosition < 0) {
				currentPosition = 0;
			}
			mPlayer.reset();
			initPlayer();

			sendBroadcast(intent);
			return currentPosition;
		}

		@Override
		public int currentTime() {
			if (mPlayer != null) {
				return mPlayer.getCurrentPosition();
			}
			return 0;
		}

		@Override
		public int TotalTime() {
			if (mPlayer != null) {
				return mPlayer.getDuration();
			}
			return 0;
		}

		@Override
		public void setCurrentTime(int progress) {
			if (mPlayer != null) {
				mPlayer.seekTo(progress);
			}

		}

		@Override
		public boolean changeState() {
			if (mPlayer.isPlaying()) {
				return true;
			} else {
				return false;
			}

		}

		@Override
		public String seekTo(int position) {
			if (mPlayer != null) {
				mPlayer.reset();
				try {
					mPlayer.setDataSource(mListData.get(position).getPath());
					mPlayer.prepare();
					currentPosition = position;
					mPlayer.start();
					return mListData.get(position).getName();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (IllegalStateException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}

			}
			return null;
		}

		@Override
		public String getCurrentTitle() {

			return mListData.get(currentPosition).getName();
		}

	}
}


Activity中

<span style="font-size:14px;">package com.scxh.android.music;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;

import Constance.MusicBean;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.scxh.android.music.adapter.MusicBaseAdapter;
import com.scxh.android.music.adapter.MusicPagerAdapter;
import com.scxh.android.service.MusicService;
import com.scxh.android.service.MusicService.MusicBinder;

public class PlayActivity extends Activity implements OnClickListener,
		OnSeekBarChangeListener {
	LayoutInflater inflater;
	ViewPager mPager;
	int oldPostion = 1;// 记录小圆点
	ImageView mDot1, mDot2, mDot3, mListImg;
	ImageButton mLastBtn, mPlayBtn, mNextBtn, mCollection;
	SeekBar mSeekBar;
	TextView mCurrentTxt, mTotalTxt, mTitle;

	ArrayList<MusicBean> mListData;
	int selectPosition;

	File file = new File(Environment.getExternalStorageDirectory() + "/music");
	boolean threadFlag = true;
	Handler mHandler = new Handler();
	// 接口对象
	MusicBinder mBinder;
	//建立连接时的两个方法
	ServiceConnection sConnection = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			mBinder = null;
		}
//建立连接后,能得到onBind中返回的IBinder对象
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mBinder = (MusicBinder) service;

		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.playactivity_layout);
		initView();// 初始化view
		receiveData();// listActivity传过来的歌曲数据和当前选中的位置
		setPagerItem();// 为ViewPager添加item布局
		setPagerListener();
		registerListener();// view注册监听

		Intent intent = new Intent(this, MusicService.class);<span style="font-family: Arial, Helvetica, sans-serif;">		</span></span>
<span style="font-size:14px;"><span style="white-space: pre;">		</span>intent.putParcelableArrayListExtra("musicList", mListData);</span>
<span style="font-size:14px;">       		intent.putExtra("currentPosition", selectPosition);
		startService(intent);//启动服务

		mTitle.setText(mListData.get(selectPosition).getName());
<span style="white-space:pre">		</span>//绑定服务
		bindService(intent, sConnection, BIND_AUTO_CREATE);

		new Thread(new UIThread()).start();		
	}

	/*
	 * 接收到listActivity传过来的歌曲数据和当前选中的位置
	 */
	private void receiveData() {
		Intent intent = getIntent();
		mListData = intent.getParcelableArrayListExtra("musicList");
		selectPosition = intent.getIntExtra("selectPosition", 0);
	}

	private void registerListener() {
		mLastBtn.setOnClickListener(this);
		mPlayBtn.setOnClickListener(this);
		mNextBtn.setOnClickListener(this);
		mSeekBar.setOnSeekBarChangeListener(this);
		mListImg.setOnClickListener(this);
	}

	private void initView() {
		inflater = LayoutInflater.from(this);
		mPager = (ViewPager) findViewById(R.id.pager_music);
		mDot1 = (ImageView) findViewById(R.id.dot1_img);
		mDot2 = (ImageView) findViewById(R.id.dot2_img);
		mDot3 = (ImageView) findViewById(R.id.dot3_img);

		mListData = new ArrayList<MusicBean>();

		mLastBtn = (ImageButton) findViewById(R.id.last_song_btn);
		mPlayBtn = (ImageButton) findViewById(R.id.palying_btn);
		mNextBtn = (ImageButton) findViewById(R.id.next_song_btn);
		mSeekBar = (SeekBar) findViewById(R.id.progressbar);
		mCurrentTxt = (TextView) findViewById(R.id.current_progress_txt);
		mTotalTxt = (TextView) findViewById(R.id.total_progress_txt);

		mListImg = (ImageView) findViewById(R.id.list_img);
		mCollection = (ImageButton) findViewById(R.id.collection_ibtn);
		mTitle = (TextView) findViewById(R.id.tile_play_txt);

	}

	ImageView img;
/*
 * PagerView添加组件
 */
	private void setPagerItem() {
		ArrayList<View> data = new ArrayList<View>();

		View item1 = inflater.inflate(R.layout.pager_item1_list_layout, null);
		MusicBaseAdapter baseAdapter = new MusicBaseAdapter(this);
		baseAdapter.setData(mListData);
		final ListView listView = (ListView) item1
				.findViewById(R.id.list_item1_pager);
		listView.setAdapter(baseAdapter);
		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				mTitle.setText(mBinder.seekTo(position));
			}
		});

		View item2 = inflater.inflate(R.layout.pager_item2_image_layout, null);
		img = (ImageView) item2.findViewById(R.id.img_music_playing);

		View item3 = inflater.inflate(R.layout.pager_item3_lyric_layout, null);

		data.add(item1);
		data.add(item2);
		data.add(item3);

		MusicPagerAdapter adapter = new MusicPagerAdapter();
		adapter.setData(data);
		mPager.setAdapter(adapter);

	}

	@SuppressWarnings("deprecation")
	private void setPagerListener() {
		final ArrayList<View> dotData = new ArrayList<View>();
		dotData.add(mDot1);
		dotData.add(mDot2);
		dotData.add(mDot3);
		mPager.setCurrentItem(1);
		dotData.get(1).setBackgroundResource(R.drawable.dot_pressed);
		mPager.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int arg0) {
				dotData.get(oldPostion).setBackgroundResource(
						R.drawable.dot_default);
				dotData.get(arg0).setBackgroundResource(R.drawable.dot_pressed);
				oldPostion = arg0;
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {

			}
		});
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		//播放/暂停的监听
		case R.id.palying_btn:

			boolean playFlag = mBinder.playMusic();
			if (playFlag == true) {
				mPlayBtn.setBackgroundResource(R.drawable.play_song_selector);
			} else {
				mPlayBtn.setBackgroundResource(R.drawable.pause_song_selector);
			}

			break;
			//点击下一首
		case R.id.next_song_btn:
			if (mBinder != null) {
				int nextPostion = mBinder.nextMusic();
				mTitle.setText(mListData.get(nextPostion).getName());
			}
			mPlayBtn.setBackgroundResource(R.drawable.play_song_selector);

			break;
			//点击上一首
		case R.id.last_song_btn:
			if (mBinder != null) {
				int lastPosition = mBinder.lastMusic();
				mTitle.setText(mListData.get(lastPosition).getName());
			}
			mPlayBtn.setBackgroundResource(R.drawable.play_song_selector);

			break;
		case R.id.list_img:
			startActivity(new Intent(this, ListActivity.class));
			finish();
			break;

		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	int mProgress;//记录拖动的进度条进度

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {
		mSeekBar.setProgress(progress);
		mProgress = progress;

	}
/*
 * 刷新界面的(SeekBar 進度及顯示)
 */
	public class UIThread implements Runnable {

		@Override
		public void run() {
			while (threadFlag) {
				if (mBinder != null) {
					mHandler.post(new Runnable() {

						@Override
						public void run() {
							int current = mBinder.currentTime();
							int total = mBinder.TotalTime();
							mSeekBar.setMax(total);
							mSeekBar.setProgress(current);
							mCurrentTxt.setText(timeFormat(current));
							mTotalTxt.setText(timeFormat(total));

						}
					});
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}

		}
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {

	}
/*
 * 拖動进度条的监听,避免因延迟造成播放卡顿,所以在onStopTrackingTouch方法中将进度传到服务器
 */
	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		mBinder.setCurrentTime(mProgress);
	}

	private String timeFormat(int time) {
		SimpleDateFormat df = new SimpleDateFormat("mm:ss");
		String timeStr = df.format(new Date(time));
		return timeStr;
	}

	
}
</span>



你可能感兴趣的:(service)