与天地兮比寿,与日月兮齐光。这篇文章主要讲述Android:(本地可通信的前台远程)Service使用全面介绍相关的知识,希望能为你提供帮助。
前言
- Service作为android四大组件之一, 应用非常广泛
- 本文将介绍Service最基础的知识: Service的生命周期
如果你对Service还未了解, 建议先阅读我写的文章:目录
Android四大组件: Service史上最全面解析
文章图片
1. Service分类 1.1 Service的类型
文章图片
1.2 特点
文章图片
2.具体使用解析 2.1 本地Service
这是最普通、最常用的后台服务Service。
2.1.1 使用步骤
- 步骤1: 新建子类继承Service类
【Android((本地可通信的前台远程)Service使用全面介绍)】需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()方法
- 步骤2: 构建用于启动Service的Intent对象
- 步骤3: 调用startService()启动Service、调用stopService()停止服务
- 步骤4: 在AndroidManifest.xml里注册Service
接下来我将用一个实例Demo进行本地Service说明
建议先下载Demo再进行阅读: ( carson.ho的Github地址) Demo_for_Service
- 步骤1: 新建子类继承Service类
需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()MyService.java
public class MyService extends Service {//启动Service之后,
就可以在onCreate()或onStartCommand()方法里去执行一些具体的逻辑
//由于这里作Demo用,
所以只打印一些语句
@
Override
public void onCreate() {
super.onCreate();
System.out.println("
执行了onCreat()"
);
}@
Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("
执行了onStartCommand()"
);
return super.onStartCommand(intent, flags, startId);
}@
Override
public void onDestroy() {
super.onDestroy();
System.out.println("
执行了onDestory()"
);
}@
Nullable
@
Override
public IBinder onBind(Intent intent) {
return null;
}
}
- 步骤2:
在主布局文件设置两个Button分别用于启动和停止Service
activity_main.xml
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
RelativeLayout xmlns:android=
"
http://schemas.android.com/apk/res/android"
xmlns:tools=
"
http://schemas.android.com/tools"
android:layout_width=
"
match_parent"
android:layout_height=
"
match_parent"
android:paddingBottom=
"
@
dimen/activity_vertical_margin"
android:paddingLeft=
"
@
dimen/activity_horizontal_margin"
android:paddingRight=
"
@
dimen/activity_horizontal_margin"
android:paddingTop=
"
@
dimen/activity_vertical_margin"
tools:context=
"
scut.carson_ho.demo_service.MainActivity"
>
<
Button
android:layout_centerInParent=
"
true"
android:id=
"
@
+
id/startService"
android:layout_width=
"
wrap_content"
android:layout_height=
"
wrap_content"
android:text=
"
启动服务"
/>
<
Button
android:layout_centerInParent=
"
true"
android:layout_below=
"
@
+
id/startService"
android:id=
"
@
+
id/stopService"
android:layout_width=
"
wrap_content"
android:layout_height=
"
wrap_content"
android:text=
"
停止服务"
/>
<
/RelativeLayout>
- 步骤3: 构建Intent对象, 并调用startService()启动Service、stopService停止服务
public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button startService;
private Button stopService;
@
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService =
(Button) findViewById(R.id.startService);
stopService =
(Button) findViewById(R.id.stopService);
startService.setOnClickListener(this);
startService.setOnClickListener(this);
}@
Override
public void onClick(View v) {
switch (v.getId()) {//点击启动Service Button
case R.id.startService:
//构建启动服务的Intent对象
Intent startIntent =
new Intent(this, MyService.class);
//调用startService()方法-传入Intent对象,以此启动服务
startService(startIntent);
//点击停止Service Button
case R.id.stopService:
//构建停止服务的Intent对象
Intent stopIntent =
new Intent(this, MyService.class);
//调用stopService()方法-传入Intent对象,以此停止服务
stopService(stopIntent);
}
}
}
- 步骤4:
在AndroidManifest.xml里注册Service
AndroidManifest.xml
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
manifest xmlns:android=
"
http://schemas.android.com/apk/res/android"
package=
"
scut.carson_ho.demo_service"
>
<
application
android:allowBackup=
"
true"
android:icon=
"
@
mipmap/ic_launcher"
android:label=
"
@
string/app_name"
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服务
<
service android:name=
"
.MyService"
>
<
/service>
<
/application>
<
/manifest>
Androidmanifest里Service的常见属性说明
属性 | 说明 | 备注 |
---|---|---|
android:name | Service的类名 | |
android:label | Service的名字 | 若不设置, 默认为Service类名 |
android:icon | Service的图标 | |
android:permission | 申明此Service的权限 | 有提供了该权限的应用才能控制或连接此服务 |
android:process | 表示该服务是否在另一个进程中运行( 远程服务) | 不设置默认为本地服务; remote则设置成远程服务 |
android:enabled | 系统默认启动 | true: Service 将会默认被系统启动; 不设置则默认为false |
android:exported | 该服务是否能够被其他应用程序所控制或连接 | 不设置默认此项为 false |
文章图片
2.1.4 Demo地址 Carson.ho的Github地址: Demo_for_Service
2.2 可通信的服务Service
- 上面介绍的Service是最基础的, 但只能单机使用, 即无法与Activity通信
- 接下来将在上面的基础用法上, 增设“与Activity通信”的功能, 即使用绑定Service服务( Binder类、bindService()、onBind() 、unbindService()、onUnbind())
接下来我将用一个实例Demo进行可通信的服务Service说明
建议先下载Demo再进行阅读: ( carson.ho的Github地址) Demo_for_Service
- 步骤1: 在新建子类继承Service类, 并新建一个子类继承自Binder类、写入与Activity关联需要的方法、创建实例
public class MyService extends Service {private MyBinder mBinder =
new MyBinder();
@
Override
public void onCreate() {
super.onCreate();
System.out.println("
执行了onCreat()"
);
}@
Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("
执行了onStartCommand()"
);
return super.onStartCommand(intent, flags, startId);
}@
Override
public void onDestroy() {
super.onDestroy();
System.out.println("
执行了onDestory()"
);
}@
Nullable
@
Override
public IBinder onBind(Intent intent) {
System.out.println("
执行了onBind()"
);
//返回实例
return mBinder;
}@
Override
public boolean onUnbind(Intent intent) {
System.out.println("
执行了onUnbind()"
);
return super.onUnbind(intent);
}//新建一个子类继承自Binder类
class MyBinder extends Binder {public void service_connect_Activity() {
System.out.println("
Service关联了Activity,并在Activity执行了Service的方法"
);
}
}
}
- 步骤2: 在主布局文件再设置两个Button分别用于绑定和解绑Service
<
?xml version=
"
1.0"
encoding=
"
utf-8"
?>
<
RelativeLayout xmlns:android=
"
http://schemas.android.com/apk/res/android"
xmlns:tools=
"
http://schemas.android.com/tools"
android:layout_width=
"
match_parent"
android:layout_height=
"
match_parent"
android:paddingBottom=
"
@
dimen/activity_vertical_margin"
android:paddingLeft=
"
@
dimen/activity_horizontal_margin"
android:paddingRight=
"
@
dimen/activity_horizontal_margin"
android:paddingTop=
"
@
dimen/activity_vertical_margin"
tools:context=
"
scut.carson_ho.demo_service.MainActivity"
>
<
Button
android:layout_centerInParent=
"
true"
android:id=
"
@
+
id/startService"
android:layout_width=
"
wrap_content"
android:layout_height=
"
wrap_content"
android:text=
"
启动服务"
/>
<
Button
android:layout_centerInParent=
"
true"
android:layout_below=
"
@
+
id/startService"
android:id=
"
@
+
id/stopService"
android:layout_width=
"
wrap_content"
android:layout_height=
"
wrap_content"
android:text=
"
停止服务"
/>
<
Button
android:layout_centerInParent=
"
true"
android:layout_below=
"
@
id/stopService"
android:id=
"
@
+
id/bindService"
android:layout_width=
"
wrap_content"
android:layout_height=
"
wrap_content"
android:text=
"
绑定服务"
/>
<
Button
android:layout_centerInParent=
"
true"
android:layout_below=
"
@
id/bindService"
android:id=
"
@
+
id/unbindService"
android:layout_width=
"
wrap_content"
android:layout_height=
"
wrap_content"
android:text=
"
解绑服务"
/>
<
/RelativeLayout>
- 步骤3: 在Activity通过调用MyBinder类中的public方法来实现Activity与Service的联系
即实现了Activity指挥Service干什么Service就去干什么的功能MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button startService;
private Button stopService;
private Button bindService;
private Button unbindService;
private MyService.MyBinder myBinder;
//创建ServiceConnection的匿名类
private ServiceConnection connection =
new ServiceConnection() {//重写onServiceConnected()方法和onServiceDisconnected()方法
//在Activity与Service建立关联和解除关联的时候调用
@
Override
public void onServiceDisconnected(ComponentName name) {
}//在Activity与Service解除关联的时候调用
@
Override
public void onServiceConnected(ComponentName name, IBinder service) {
//实例化Service的内部类myBinder
//通过向下转型得到了MyBinder的实例
myBinder =
(MyService.MyBinder) service;
//在Activity调用Service类的方法
myBinder.service_connect_Activity();
}
};
@
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService =
(Button) findViewById(R.id.startService);
stopService =
(Button) findViewById(R.id.stopService);
startService.setOnClickListener(this);
stopService.setOnClickListener(this);
bindService =
(Button) findViewById(R.id.bindService);
unbindService =
(Button) findViewById(R.id.unbindService);
bindService.setOnClickListener(this);
unbindService.setOnClickListener(this);
}@
Override
public void onClick(View v) {
switch (v.getId()) {//点击启动Service
case R.id.startService:
//构建启动服务的Intent对象
Intent startIntent =
new Intent(this, MyService.class);
//调用startService()方法-传入Intent对象,以此启动服务
startService(startIntent);
break;
//点击停止Service
case R.id.stopService:
//构建停止服务的Intent对象
Intent stopIntent =
new Intent(this, MyService.class);
//调用stopService()方法-传入Intent对象,以此停止服务
stopService(stopIntent);
break;
//点击绑定Service
case R.id.bindService:
//构建绑定服务的Intent对象
Intent bindIntent =
new Intent(this, MyService.class);
//调用bindService()方法,以此停止服务bindService(bindIntent,connection,BIND_AUTO_CREATE);
//参数说明
//第一个参数:Intent对象
//第二个参数:上面创建的Serviceconnection实例
//第三个参数:标志位
//这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service
//这会使得MyService中的onCreate()方法得到执行,
但onStartCommand()方法不会执行
break;
//点击解绑Service
case R.id.unbindService:
//调用unbindService()解绑服务
//参数是上面创建的Serviceconnection实例
unbindService(connection);
break;
default:
break;
}
}
}
2.2.2 测试结果
文章图片
2.2.3 Demo
carson.ho的Github地址: Demo_for_Service
2.3 前台Service 前台Service和后台Service( 普通) 最大的区别就在于:
- 前台Service在下拉通知栏有显示通知(
如下图)
,
但后台Service没有;
文章图片
- 前台Service优先级较高,
不会由于系统内存不足而被回收;
后台Service优先级较低,
当系统出现内存不足情况时,
很有可能会被回收
@
Override
public void onCreate() {
super.onCreate();
System.out.println("
执行了onCreat()"
);
//添加下列代码将后台Service变成前台Service
//构建"
点击通知后打开MainActivity"
的Intent对象
Intent notificationIntent =
new Intent(this,MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this,0,notificationIntent,0);
//新建Builer对象
Notification.Builder builer =
new Notification.Builder(this);
builer.setContentTitle("
前台服务通知的标题"
);
//设置通知的标题
builer.setContentText("
前台服务通知的内容"
);
//设置通知的内容
builer.setSmallIcon(R.mipmap.ic_launcher);
//设置通知的图标
builer.setContentIntent(pendingIntent);
//设置点击通知后的操作Notification notification =
builer.getNotification();
//将Builder对象转变成普通的notification
startForeground(1, notification);
//让Service变成前台Service,并在系统的状态栏显示出来}
2.3.2 测试结果 运行后, 当点击Start Service或Bind Service按钮, Service就会以前台Service的模式启动( 通知栏上有通知) , 如下图
文章图片
2.4 远程Service 具体请看我写的另外一篇文章:
Android: 远程服务Service( 含AIDL & IPC讲解)
3. 使用场景
- 通过上述描述, 你应该对Service类型及其使用非常了解;
- 那么, 我们该什么时候用哪种类型的Service呢?
- 各种Service的使用场景请看下图:
文章图片
- 本文对Service的使用进行了全面解析( 本地、可通信、前台和远程Service)
- 如果你还想了解关于Service的其他知识, 请浏览以下文章:
Android四大组件: Service史上最全面解析
Android: Service生命周期最全面解析
Android: ( 本地、可通信的、前台、远程) Service使用全面介绍
Android: 远程服务Service( 含AIDL & IPC讲解)
Android多线程全面解析: IntentService用法& 源码
- 接下来会介绍继续介绍Android开发中的相关知识,
感兴趣的同学可以继续关注carson_ho的微信公众号
文章图片
文章图片
推荐阅读
- android学习笔记——全局改变应用的字体
- Android(远程服务Service(含AIDL & IPC讲解))
- Android 热修复方案分析
- 6.5 为什么Android用Java不用c实现()
- 6.3 Android Framework
- Android 对电话进行监听和挂断
- Android 登录界面与首页的设计
- android studio2.0 搭建Robotium环境--apk测试没有混淆只有签名
- Android官方开发文档Training系列课程中文版(目录)