service 用于后台完成用户指定的操作,它可以用于播放音乐,文件下载和检查新消息推送等
Service的分类
Started Service 当应用程序组件通过startService() 方法启动Service时,Service处于启动状态,一旦启动,Service能在后台无限期运行,其自身必须调用stopSelf()方法或者其他组件调用stopService()来停止Service
Bound Service 当应用程序组件通过调用bindService()方法绑定到Service时,Service处于绑定状态,多个组件可以同时绑定一个Service上,当他们都解除绑定时,Service被销毁
Service的生命周期
关注Service如何创建和销毁,
通过startService方法启动
Service基本使用
1.创建与配置
package com.example.testapplication.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
// 在Serice销毁时调用
@Override
public void onDestroy() {
Log.i("Service:","service已停止");
super.onDestroy();
}
// service创建时被调用
@Override
public void onCreate() {
Log.i("Service:","service已创建");
super.onCreate();
}
// 每次启动Service时调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
Log.i("Service:","Service已启动");
// 模拟一段耗时任务
long endTime = System.currentTimeMillis()+ 5 *1000;
while (System.currentTimeMillis() < endTime){
synchronized (this){
try {
wait(endTime -System.currentTimeMillis());
}catch (Exception e){
e.printStackTrace();
}
}
}
stopSelf(); // 停止Service
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
}
案例1:控制游戏背景音乐
在res目录下创建raw子目录 将MP3文件放入
package com.example.testapplication.service;
import android.app.Service;
import android.content.Intent;
import android.media.MediaParser;
import android.media.MediaPlayer;
import android.os.IBinder;
import com.example.testapplication.R;
public class MusicService extends Service {
public MusicService() {
}
static boolean isplay; // 定义当前播放状态
MediaPlayer player; // MediaPlayer对象
@Override
public IBinder onBind(Intent intent) { // 必须实现的绑定方法
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
//super.onCreate();
//创建MediaPlayer对像并加载播放的音乐文件
player = MediaPlayer.create(this, R.raw.music);
}
@Override
// 实现音乐的播放
public int onStartCommand(Intent intent, int flags, int startId) {
if(!player.isPlaying()){ // 如果没有播放音乐
player.start(); // 播放音乐
isplay = player.isPlaying(); //当前状态正在播放音乐
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() { // 停止音乐的播放
player.stop(); //停止音频的播放
isplay = player.isPlaying(); //当前状态没有播放音乐
player.release(); //释放资源
super.onDestroy();
}
}
package com.example.testapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import com.example.testapplication.service.MusicService;
public class serviceMusic extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_music);
// 设置全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
ImageButton btn_play = (ImageButton) findViewById(R.id.btn_play); // 获取播放/停止 按钮
// 启动服务与停止服务 实现播放背景音乐与停止播放背景音乐
btn_play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(MusicService.isplay == false){ //判断音乐播放的状态
// 启动服务,从而实现播放背景音乐
startService(new Intent(serviceMusic.this,MusicService.class));
// 替换播放背景音乐图标
((ImageButton) view).setImageDrawable(getResources().getDrawable(R.drawable.bgplay,null));
}else{
// 停止服务,从而实现停止播放背景音乐
stopService(new Intent(serviceMusic.this,MusicService.class));
((ImageButton) view).setImageDrawable(getResources().getDrawable(R.drawable.bgs,null));
}
}
});
}
@Override
protected void onStart() { //实现进入界面时,启动背景音乐服务
//启动服务,从而实现播放背景音乐
startService(new Intent(serviceMusic.this, MusicService.class));
super.onStart();
}
}
Bound Service
当应用程序组件通过调用bindService() 方法绑定到Service时,Service处于绑定状态,多个组件可以同时绑定到Service上
模拟双色球彩票的随机选号
package com.example.testapplication.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MyBinder extends Service {
public MyBinder() {
}
public class MyBind extends Binder { //创建MyBinder内部类并获取服务对象与Service状态
public MyBinder getService(){ //创建获取Service的方法
return MyBinder.this; // 返回当前Service类
}
}
@Override
public IBinder onBind(Intent intent) { //必须实现的绑定方法
// TODO: Return the communication channel to the service.
//throw new UnsupportedOperationException("Not yet implemented");
return new MyBind(); //返回MyBind服务对象
}
public List getRandomNumber(){ //创建获取随机号码的方法
List resArr = new ArrayList();// 创建ArrayList数组
String strNumber = "";
for(int i = 0; i<7;i++){
int number = new Random().nextInt(33) + 1;
//把生成的随机数格式化为两位的字符串
if (number<10) { //在数字1~9前加0
strNumber = "0" + String.valueOf(number);
} else {
strNumber=String.valueOf(number);
}
resArr.add(strNumber);
}
return resArr;
}
@Override
public void onDestroy() { //销毁该Service
super.onDestroy();
}
}
package com.example.testapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.example.testapplication.service.MyBinder;
import java.util.List;
public class BoundService extends AppCompatActivity {
MyBinder binder; //声明BinderService
int[] tvid = {R.id.tView1,R.id.tView2,R.id.tView3,R.id.tView4,R.id.tView5,
R.id.tView6,R.id.tView7};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bound_service);
Button btn_random = (Button) findViewById(R.id.btn);
btn_random.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
List number = binder.getRandomNumber(); //获取BinderService类中的随机数数组
for(int i = 0; i < number.size(); i++){ //遍历数组并显示
TextView tv = (TextView) findViewById(tvid[i]); //获取文本框组件对象
String strNumber = number.get(i).toString(); //将获取的号码转为String类型
tv.setText(strNumber); //显示生成的随机号码
}
}
});
}
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this,MyBinder.class);
// 应用程序组件 能调用bindService 方法绑定到Service
bindService(intent,conn,BIND_AUTO_CREATE); //绑定指定Service
}
@Override
protected void onStop() { //设置关闭Activity时解除与后台Service的绑定
super.onStop();
unbindService(conn); //解除绑定Service
}
private ServiceConnection conn = new ServiceConnection() { //设置与后台Service进行通讯
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
binder = ((MyBinder.MyBind) iBinder).getService(); //获取后台Service信息
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
}