1 service是什么
Service是Android系统中的四大组件之一,它是一种长生命周期的,没有可视化界面,运行于后台的一种服务程序。
2 service分类
3 service启动方式
3.1 startService显示启动
// AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.myapplication"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"><activity android:name=".StartServiceActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><service android:name=".StartService" /></application></manifest>
// StartSeviceActivity.java
package com.example.myapplication;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;//import com.ttit.helloworld.R;public class StartServiceActivity extends AppCompatActivity {private Button start;private Button stop;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.service_layout);start = (Button) findViewById(R.id.btnstart);stop = (Button) findViewById(R.id.btnstop);final Intent intent = new Intent(StartServiceActivity.this, StartService.class);start.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {startService(intent);}});stop.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {stopService(intent);}});}
}
// StartService.java
package com.example.myapplication;import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;import android.os.Bundle;public class StartService extends Service {private final String TAG = "service";//必须要实现的方法@Overridepublic IBinder onBind(Intent intent) {Log.e(TAG, "onBind方法被调用!");return null;}//Service被创建时调用@Overridepublic void onCreate() {Log.e(TAG, "onCreate方法被调用!");super.onCreate();}//Service被启动时调用@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.e(TAG, "onStartCommand方法被调用!");return super.onStartCommand(intent, flags, startId);}//Service被关闭之前回调@Overridepublic void onDestroy() {Log.e(TAG, "onDestory方法被调用!");super.onDestroy();}
}
// service_layout.xml<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/btnstart"android:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:text="开始服务"/><Buttonandroid:id="@+id/btnstop"android:layout_width="0dp"android:layout_weight="1"android:layout_height="wrap_content"android:text="停止服务"/></LinearLayout>
1> 通过按钮"开始服务"启动service
final Intent intent = new Intent(StartServiceActivity.this, StartService.class);start.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {startService(intent);}});
2> 创建StartService 继承service类
public class StartService extends Service
在StartService中实现 onBind,onCreate,onStartCommand, onDestroy方法
3> 在AndroidManifest.xml 清单文件中注册
<service android:name=".StartService" />
4> 运行结果
点击开始服务,运行结果如下:
多次点击开始服务,运行结果如下:
点击停止服务,运行结果如下:
3.2 bindService绑定启动
//AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.myapplication"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"><activity android:name=".BindServiceActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><service android:name=".BindService" /></application></manifest>
// BindServiceActivity.java
package com.example.myapplication;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;public class BindServiceActivity extends AppCompatActivity {private Button btnbind;private Button btncancel;private Button btnstatus;//保持所启动的Service的IBinder对象,同时定义一个ServiceConnection对象private BindService.MyBinder binder;private ServiceConnection conn = new ServiceConnection() {//Activity与Service断开连接时回调该方法@Overridepublic void onServiceDisconnected(ComponentName name) {Log.e("service", " ------Service DisConnected-------");}//Activity与Service连接成功时回调该方法@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {Log.e("service", " ------Service Connected------ - ");binder = (BindService.MyBinder) service;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.bind_service_layout);btnbind = (Button) findViewById(R.id.btnbind);btncancel = (Button) findViewById(R.id.btncancel);btnstatus = (Button) findViewById(R.id.btnstatus);final Intent intent = new Intent(BindServiceActivity.this, BindService.class);btnbind.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//绑定servicebindService(intent, conn, Service.BIND_AUTO_CREATE);}});btncancel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//解除service绑定unbindService(conn);}});btnstatus.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(getApplicationContext(), "Service的count的值为:"+ binder.getCount(), Toast.LENGTH_SHORT).show();}});}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(conn); // 销毁Activity时需要解绑Service}
}
// BindService
package com.example.myapplication;import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;public class BindService extends Service {private final String TAG = "service";private int count;private boolean quit;//定义onBinder方法所返回的对象private MyBinder binder = new MyBinder();public class MyBinder extends Binder {public int getCount() {return count;}}//必须实现的方法,绑定改Service时回调该方法@Overridepublic IBinder onBind(Intent intent) {Log.e(TAG, "onBind方法被调用!");return binder;}//Service被创建时回调@Overridepublic void onCreate() {super.onCreate();Log.e(TAG, "onCreate方法被调用!");//创建一个线程动态地修改count的值new Thread() {public void run() {while (!quit) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}count++;Log.e(TAG, "count = " + count);}}}.start();}//Service断开连接时回调@Overridepublic boolean onUnbind(Intent intent) {Log.e(TAG, "onUnbind方法被调用!");return true;}//Service被关闭前回调@Overridepublic void onDestroy() {super.onDestroy();this.quit = true;Log.e(TAG, "onDestroyed方法被调用!");}@Overridepublic void onRebind(Intent intent) {Log.e(TAG, "onRebind方法被调用!");super.onRebind(intent);}
}
layout截图如下:
运行结果如下:
点击绑定SERVICE:
4 service生命周期
startService启动的生命周期
onCreate() 当Service第一次被创建时,由系统调用。
onStartCommand() 当startService方法启动Service时,该方法被调用。
onDestroy() 当Service不再使用时,由系统调用。
注意:一个startService只会创建一次,销毁一次,但可以开始多次,因此,onCreate()和onDestroy()方法只会被调用一次,而onStartCommand()方法会被调用多次。
bindService启动的生命周期
onCreate() 当Service被创建时,由系统调用。
onBind() 当bindService方法启动Service时,该方法被调用。
onUnbind() 当unbindService方法解除绑定时,该方法被调用。
onDestroy() 当Service不再使用时,由系统调用。
注意:一个bindService可以创建多次,销毁多次,重复使用。
5 service和thread的区别
结论:Service和Thread之间没有任何关系
之所以有不少人会把它们联系起来,主要因为Service的后台概念
后台的定义:后台任务运行完全不依赖UI,即使Activity被销毁,或者程序被关闭,只要进程还在,后台任务就可以继续运行
其实二者存在较大的区别,如下图:
一般来说,会将Service和Thread联合着用,即在Service中再创建一个子线程(工作线程)去处理耗时操作逻辑,如下代码:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//新建工作线程new Thread(new Runnable() { @Override public void run() { // 开始执行后台任务 } }).start(); return super.onStartCommand(intent, flags, startId);
} class MyBinder extends Binder { public void service_connect_Activity() { //新建工作线程new Thread(new Runnable() { @Override public void run() { // 执行具体的下载任务 } }).start(); } }