1 Service了解
主要作用处理一些好事的逻辑,或者执行某些需要长期运行的任务,必要的时候程序退出则Service可以在后台继续保持运行状态
2 Service生命周期 onCreate ,onStartCommand ,onStart , onDestroy
Service开启的时候依次执行 onCreate ,onStartCommand ,onStart
Service 调用stopService 时候执行 onDestroy
bindService方法执行Service中的onBind 方法
unbindService 方法执行Service中的onUnbind 方法
3 Service与线程使用与区别
1 )Service可以脱离Activity独立运行,2)可以运行在后台 3)与主线程是一个线程
有一些东西执行比较耗时,比如下载,但是我下载同时还要做其他事情,这时候使用Service虽然Activity退出了,但是程序依然运行,因为主线程与Service在
一个线程中,会阻碍主线程,这时候可以在Service中启动一个单独的子线程即可
总结:当一个任务需要独立Activity运行,这时候用Service ,Service比较耗时就可以单独启动Thread来使用
4 Service可以是前台Service,也可以做成后台不可见的Service
5 使用
1)类继承Service 2)在主的xml中进行注册 3)Activity开启与使用
代码:
1 Activity
public class ServiceMainActivity extends Activity {
//为日志工具设置标签
private static String TAG = "MusicService";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_main);
Log.d("ServiceMainActivity", "ServiceMainActivity thread id is " + Thread.currentThread().getId());
//输出Toast消息和日志记录
Toast.makeText(this, "ServiceMainActivity",
Toast.LENGTH_SHORT).show();
Log.e(TAG, "ServiceMainActivity");
initlizeViews();
}
private void initlizeViews(){
Button btnStart = (Button)findViewById(R.id.startMusic);
Button btnStop = (Button)findViewById(R.id.stopMusic);
Button btnBind = (Button)findViewById(R.id.bindMusic);
Button btnUnbind = (Button)findViewById(R.id.unbindMusic);
//定义点击监听器
OnClickListener ocl = new OnClickListener() {
@Override
public void onClick(View v) {
//显示指定 intent所指的对象是个 service
Intent intent = new Intent( ServiceMainActivity.this ,MusicService.class);
switch(v.getId()){
case R.id.startMusic:
//开始服务
startService(intent);
break;
case R.id.stopMusic:
//停止服务
stopService(intent);
break;
case R.id.bindMusic:
//绑定服务
bindService(intent, conn, Context.BIND_AUTO_CREATE);
break;
case R.id.unbindMusic:
//解绑服务
unbindService(conn);
break;
}
}
};
//绑定点击监听
btnStart.setOnClickListener(ocl);
btnStop.setOnClickListener(ocl);
btnBind.setOnClickListener(ocl);
btnUnbind.setOnClickListener(ocl);
}
//定义服务链接对象
final ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(ServiceMainActivity.this, "ServiceMainActivity onSeviceDisconnected"
, Toast.LENGTH_SHORT).show();
Log.e(TAG, "ServiceMainActivity onSeviceDisconnected");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(ServiceMainActivity.this, "ServiceMainActivity onServiceConnected"
,Toast.LENGTH_SHORT).show();
Log.e(TAG, "ServiceMainActivity onServiceConnected");
MusicService.MyBinder bind = (MusicService.MyBinder)service;
bind.startDownload();
Log.e(TAG, "bind====" +bind);
}
};
}
2 SERvice
public class MusicService extends Service {
//为日志工具设置标签
private static String TAG = "MusicService";
//定义音乐播放器变量
private MediaPlayer mPlayer;
public MyBinder myBinder = new MyBinder();
//该服务不存在需要被创建时被调用,不管startService()还是bindService()都会启动时调用该方法
@Override
public void onCreate() {
Toast.makeText(this, "MusicSevice onCreate()"
, Toast.LENGTH_SHORT).show();
Log.e(TAG, "MusicSerice onCreate()");
Log.d("MusicService", "MusicService thread id is " + Thread.currentThread().getId());
//后台的Service使用
mPlayer = MediaPlayer.create(getApplicationContext(),R.raw.ring);
// 设置可以重复播放
mPlayer.setLooping(true);
//前台的Service使用
Notification notification = new Notification(R.drawable.ic_launcher,
"有通知到来", System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ServiceMainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(this, "这是通知的标题", "这是通知的内容",
pendingIntent);
startForeground(1, notification);
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
Toast.makeText(this, "MusicSevice onStart()"
, Toast.LENGTH_SHORT).show();
Log.e(TAG, "MusicSerice onStart()");
mPlayer.start();
super.onStart(intent, startId);
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "MusicSerice onStartCommand()");
new Thread(new Runnable() {
@Override
public void run() {
// 开始执行后台任务
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Toast.makeText(this, "MusicSevice onDestroy()"
, Toast.LENGTH_SHORT).show();
Log.e(TAG, "MusicSerice onDestroy()");
mPlayer.stop();
super.onDestroy();
}
//其他对象通过bindService 方法通知该Service时该方法被调用
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(this, "MusicSevice onBind()"
, Toast.LENGTH_SHORT).show();
Log.e(TAG, "MusicSerice onBind()");
mPlayer.start();
return null;
}
//其它对象通过unbindService方法通知该Service时该方法被调用
@Override
public boolean onUnbind(Intent intent) {
Toast.makeText(this, "MusicSevice onUnbind()"
, Toast.LENGTH_SHORT).show();
Log.e(TAG, "MusicSerice onUnbind()");
mPlayer.stop();
return super.onUnbind(intent);
}
//简历与activity的联系类
class MyBinder extends Binder {
public void startDownload() {
new Thread(new Runnable() {
@Override
public void run() {
// 执行具体的下载任务
}
}).start();
Log.d("TAG", "startDownload() executed");
// 执行具体的下载任务
}
}
}
3 xml布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Welcome to Andy's blog!" android:textSize="16sp"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="音乐播放服务"/> <Button android:id="@+id/startMusic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开启音乐播放服务"/> <Button android:id="@+id/stopMusic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止音乐播放服务"/> <Button android:id="@+id/bindMusic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="绑定音乐播放服务"/> <Button android:id="@+id/unbindMusic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="解除 ——绑定音乐播放服务"/> </LinearLayout>