服务(Service)
是Android中的四大组件之一,它能够长期在后台运行,服务是不需要提供用户界面。即使用户切到另一应用程序,服务仍可以在后台运行。
1.Service 的创建
1.Service 的创建
服务创建就是新建一个java类,让他继承Service,添加未实现的方法
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
2.在清单文件中配置
其实这就类似javaweb在web.xml配置过滤器一样,在AndroidManifest.xml文件中application节点下配置,与activity同级;
一下贴出所有的 application 节点,方便理解
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".RandomService">
<intent-filter>
<action android:name="www.lyd.random"/>
</intent-filter>
</service>
</application>
主要代码:
<service android:name=".RandomService">//服务类,可以直接复制限定名
<intent-filter>
<action android:name="www.lyd.random"/>//对应的action
</intent-filter>
</service>
2. Service 的生命周期
1、直接启动服务
当 startService(intent);//启动service 时候
启动服务可以多次运行,但是oncreate只执行一次
服务会执行onCreate() onStartCommand()方法,服务处于运行状态,直到自身调用stopSelf()方法或者其他组件调用stopService()方法时服务停止,最终被系统销毁。
服务会长期的在后台运行,并且服务的状态与开启者的状态没有关系。
Intent intent = new Intent();//添加action意图
intent.setAction("www.lyd.random");
这个就是android5.0的兼容问题,说以要加上
intent.setPackage(MainActivity.this.getPackageName());//兼容Android 5.0
首先运行的是
@Override
public void onCreate() {
Log.i("onCreate","服务已经启动");//只会启动一次,在服务没停止之前,不管在启动多少次服务,只运行一次
super.onCreate();
}
其次
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int num = (int) (Math.random()*10);
Log.i("random","num=" + num);
return super.onStartCommand(intent, flags, startId);
}
多次点击
stopService(intent);//销毁服务,未开启时不会销毁
2、使用绑定服务
服务会执行onCreate() -> onBind()方法,服务处于绑定状态, 客户端通过unbindService()方法关闭连接,解除绑定时,系统将直接销毁服务。
服务与开启者的状态有关,当调用者销毁了,服务也会被销毁。
绑定服务只能运行一次,也就是绑定之后不能再继续绑定服务
这里就不粘贴代码,最后放总代码
绑定服务会先执行onCreate(),然后onBind方法,最后执行ServiceConnection的回调方法onServiceConnected;
运行绑定服务
发现,onServiceConnected没有输出
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("MainActivity","服务已经连接 传递信息");
}
原因就是在onBind返回的是null,应该返回一个IBinder,在onServiceConnected可以调用。
多次运行绑定服务也只会运行一次
在点击启动服务,只会运行onStartCommand
最后解除绑定
3. Service 的通信
在Android系统中,服务的通信方式有两种,一种是本地服务通信,一种是远程服务通信。
本地服务通信是指应用程序内部的通信,而远程服务通信是指两个应用程序之间的通信。使用这两种方式进行通信时必须满足一个前提,就是服务必须以绑定方式开启
就介绍到这里,有问题请帮忙指证,谢谢!
接下来粘贴代码
xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myservice">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".RandomService">
<intent-filter>
<action android:name="www.lyd.random"/>
</intent-filter>
</service>
</application>
</manifest>
xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/start_Service"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="启动服务"/>
<Button
android:id="@+id/stop_Service"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="停止服务"/>
<Button
android:id="@+id/upBind_Service"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="绑定服务"/>
<Button
android:id="@+id/outBind_Service"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="解绑服务"/>
</LinearLayout>
</LinearLayout>
package com.example.myservice;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private onClickListener listener = new onClickListener();
private ReceiveServiceMessage conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.start_Service).setOnClickListener(listener);
findViewById(R.id.stop_Service).setOnClickListener(listener);
findViewById(R.id.upBind_Service).setOnClickListener(listener);
findViewById(R.id.outBind_Service).setOnClickListener(listener);
conn = new ReceiveServiceMessage();
}
class ReceiveServiceMessage implements ServiceConnection{
//绑定回调方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
RandomService.myBinder Binder = (RandomService.myBinder)service;
Log.i("MainActivity","服务已经连接 传递信息" + Binder.getNumber());
}
//解绑回调方法
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("MainActivity","服务断开连接");
}
}
class onClickListener implements View.OnClickListener{
@Override
public void onClick(View v) {
Intent intent = new Intent();//添加action意图
intent.setAction("www.lyd.random");
intent.setPackage(MainActivity.this.getPackageName());//兼容Android 5.0
switch (v.getId()){
case R.id.start_Service:
//显示意图启动Service
/**
* Intent intent = new Intent(com.example.myservice.RandomService.class);
* context.startService(intent);
**/
startService(intent);//启动service
break;
case R.id.stop_Service:
stopService(intent);//销毁服务,未开启时不会销毁
break;
case R.id.upBind_Service:
bindService(intent,conn, Service.BIND_AUTO_CREATE);//绑定服务只执行一次
break;
case R.id.outBind_Service:
Boolean isBind = bindService(intent, conn, Context.BIND_AUTO_CREATE);
if(isBind){
unbindService(conn);
isBind = false;
}
break;
}
}
}
}
package com.example.myservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class RandomService extends Service {
class myBinder extends Binder{
int number;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
myBinder MyBinder = new myBinder();
int number = (int) (Math.random()*100) + 1;
String str = "onBind通信, 随机信息:" + number;
Log.i("onBind","绑定了服务 "+str);
MyBinder.setNumber(number);
return MyBinder;//要返回一个Binder,返回null,onServiceConnected就不会进行
}
@Override
public boolean onUnbind(Intent intent) {
Log.i("onUnBind","解除绑定服务");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
Log.i("onCreate","服务已经启动");//只会启动一次,在服务没停止之前,不管在启动多少次服务,只运行一次
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int num = (int) (Math.random()*10);
Log.i("random","num=" + num);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i("onDestroy","服务已经销毁");
super.onDestroy();
}
}
谢谢大家的阅读!