Service服务
服务是安卓四大组件之一,能够长期运行在后台,且不需要提供用户界面;服务的状态与开启者没有关系
服务的创建
通过startService()
启动,需要调stopService()
才能停止
通过bindService()
绑定,需要与unbindService()
解绑后,服务才被销毁
官方解释
服务的整个生命周期从调用 onCreate() 开始起,到 onDestroy() 返回时结束。与 Activity 类似,服务也在 onCreate() 中完成初始设置,并在 onDestroy() 中释放所有剩余资源。例如,音乐播放服务可以在 onCreate() 中创建用于播放音乐的线程,然后在 onDestroy() 中停止该线程。 无论服务是通过 startService() 还是 bindService() 创建,都会为所有服务调用 onCreate() 和 onDestroy() 方法。 服务的有效生命周期从调用 onStartCommand() 或 onBind() 方法开始。每种方法均有 Intent 对象,该对象分别传递到 startService() 或 bindService()。 对于启动服务,有效生命周期与整个生命周期同时结束(即便是在 onStartCommand() 返回之后,服务仍然处于活动状态)。对于绑定服务,有效生命周期在 onUnbind() 返回时结束。
服务的生命周期 有五种方法
onCreate()
创建
onStartCommand()
开始
onDestroy()
销毁
onBind()
绑定
onUnbind()
解绑
三种状态
启动 startService() 启动服务,处于“启动”状态,启动后不管启动服务的组件是否销毁,服务依然运行
绑定 bindService() 绑定服务,处于“绑定”状态,服务只会在组件与其绑定时运行
启动且绑定 调用onStartCommand() 和 onBind() ,处于“启动且绑定”状态
1.在整个生命周期内,只有onstartCommand() 能被多次调用,绑定和解绑都只能调用一次 2.绑定后没有解绑,无法 使用stopService()将其停止 3.如果已经onCreate(),那么startService()将只 调用startCommand() 4.如果是以bindService开启,那么使用unbindService时就会自动调用 onDestroy销毁
服务的通讯
服务的必须以绑定服务形式才能通讯
本地服务通讯:应用内的通讯
远程服务通讯:应用之间的通讯
服务例子
模拟两种服务
样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?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" android:orientation="vertical" > <Button android:id="@+id/start_service1" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="start1" android:text="直接开启" /> <Button android:id="@+id/stop_service1" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="stop1" android:text="结束" /> <Button android:id="@+id/start_service2" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="start2" android:text="绑定开启" /> <Button android:id="@+id/stop_service2" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="stop2" android:text="结束" /> </LinearLayout>
Activity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package com.example.musicplayer; 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; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button startService1 = (Button) findViewById(R.id.start_service1); Button stopService1 = (Button) findViewById(R.id.stop_service1); Button startService2 = (Button) findViewById(R.id.start_service2); Button stopService2 = (Button) findViewById(R.id.stop_service2); } public void start1(View view){ Intent startIntent = new Intent(this, MyService.class); startService(startIntent); } public void stop1(View view){ Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); } private ServiceConnection connection = new ServiceConnection() { private MyService.MyBinder myBinder; @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder = (MyService.MyBinder) service; myBinder.dosomething(); } }; public void start2(View view){ Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE); } public void stop2(View view){ unbindService(connection); } }
服务类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package com.example.musicplayer; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; import android.widget.Toast; public class MyService extends Service { private MyBinder mBinder = new MyBinder(); @Override public void onCreate() { super.onCreate(); Toast.makeText(this, "onCreate()", Toast.LENGTH_SHORT).show(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(this, "onStartCommand()", Toast.LENGTH_SHORT).show(); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.e("日志", "已清除"); } @Override public IBinder onBind(Intent intent) { return mBinder; } class MyBinder extends Binder { public void dosomething(){ Log.e("日志", "服务被activity调用"); } } }
manifest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/distribution" package="com.example.musicplayer"> <dist:module dist:instant="true" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="服务示例" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <service android:name=".MyService" android:enabled="true" android:exported="true"></service> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
结果