Android 四大组件 (二) Service 使用
一. Service 介绍
Service属于android四大组件之一,在很多地方经常被用到。开启Service有两种不同的方式:startService和bindService。不同的开启方式,Service执行的生命周期方法也不同。
分 显示/隐示调用 ,但是官网推荐用显式的方式启动Service。下面 service使用 用的就是显示调用;注意事项用的就是隐示调用,在5.0系统上隐示调用会报错。所以这里只介绍使用显示调用。
不能再service里做耗时操作,否则ANR;需要开辟子线程进行耗时操作处理。
二.Service 使用
1.startService使用。
Intent intent = new Intent(this, TestService.class);
Log.w(Tag, "activity====启动服务");
startService(intent);
执行效果:

Log.w(Tag, "activity====停止服务"); stopService(intent);
执行效果:

2.bindService绑定.
private class MyConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//只有当我们自己写的MyService的onBind方法返回值不为null时,才会被调用
Log.e("call", "onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 这个方法只有出现异常时才会调用,服务器正常退出不会调用。
Log.e("call", "onServiceDisconnected");
}
}
Log.w(Tag, "activity====绑定服务");
MyConnection conn = new MyConnection(); //第一个参数:Intent意图 // 第二个参数:是一个接口,通过这个接口接收服务开启或者停止的消息,并且这个参数不能为null // 第三个参数:开启服务时的操作,BIND_AUTO_CREATE代表自动创建service bindService(service, conn, BIND_AUTO_CREATE); bindService(intent, conn, BIND_AUTO_CREATE);
执行效果:

Log.w(Tag, "activity====解绑服务");
unbindService(conn);
执行效果:

3.区别:
以下摘自网络,后续验证:
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。
使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。
三.Service 注意事项:
在5.0系统上使用如下方式start或者bind启动service时候:
Intent intent = new Intent();
intent.setAction("com.example.user.firstapp.FIRST_SERVICE");
bindService(intent,coon,Service.BIND_AUTO_CREATE);
startService(intent);

android 5.0上,报错:IllegalArgumentException: Service Intent must be explicit
原因是:Android5.0中service的intent一定要显性声明!!!
四.附上核心activity代码:
package com.example.hp.testapp;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.example.hp.testapp.service.TestService;
import org.w3c.dom.Text;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private String Tag = "TestServiceTag";
private TextView tv_btn_start;
private TextView tv_btn_stop;
private TextView tv_btn_bind;
private TextView tv_btn_unbind;
Intent intent;
MyConnection conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(this, TestService.class);
conn = new MyConnection();
initView();
initListener();
}
private void initView() {
tv_btn_start = (TextView) findViewById(R.id.tv_btn_start);
tv_btn_stop = (TextView) findViewById(R.id.tv_btn_stop);
tv_btn_bind = (TextView) findViewById(R.id.tv_btn_bind);
tv_btn_unbind = (TextView) findViewById(R.id.tv_btn_unbind);
}
private void initListener() {
tv_btn_start.setOnClickListener(this);
tv_btn_stop.setOnClickListener(this);
tv_btn_bind.setOnClickListener(this);
tv_btn_unbind.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_btn_start:
/**
* 启动服务
*/
Log.w(Tag, "activity====启动服务");
startService(intent);
break;
case R.id.tv_btn_stop:
/**
* 停止服务
*/
Log.w(Tag, "activity====停止服务");
stopService(intent);
break;
case R.id.tv_btn_bind:
/**
* 绑定服务
*/
Log.w(Tag, "activity====绑定服务");
//第一个参数:Intent意图
// 第二个参数:是一个接口,通过这个接口接收服务开启或者停止的消息,并且这个参数不能为null
// 第三个参数:开启服务时的操作,BIND_AUTO_CREATE代表自动创建service bindService(service, conn, BIND_AUTO_CREATE);
bindService(intent, conn, BIND_AUTO_CREATE);
break;
case R.id.tv_btn_unbind:
/**
* 解绑服务
*/
Log.w(Tag, "activity====解绑服务");
if (conn != null) {
unbindService(conn);
}
default:
break;
}
}
@Override
protected void onStart() {
Log.w(Tag, "activity====onStart");
super.onStart();
}
@Override
protected void onRestart() {
Log.w(Tag, "activity====onRestart");
super.onRestart();
}
@Override
public void onStateNotSaved() {
Log.w(Tag, "activity====onStateNotSaved");
super.onStateNotSaved();
}
@Override
protected void onResume() {
Log.w(Tag, "activity====onResume");
super.onResume();
}
@Override
protected void onPause() {
Log.w(Tag, "activity====onPause");
super.onPause();
}
@Override
protected void onStop() {
Log.w(Tag, "activity====onStop");
super.onStop();
}
@Override
protected void onDestroy() {
Log.w(Tag, "activity====onDestroy");
super.onDestroy();
}
private class MyConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//只有当我们自己写的MyService的onBind方法返回值不为null时,才会被调用
Log.e("call", "onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 这个方法只有出现异常时才会调用,服务器正常退出不会调用。
Log.e("call", "onServiceDisconnected");
}
}
}
浙公网安备 33010602011771号