02 Android基础--service
- 什么是service?
- service的demo使用
- Service的种类
- 前台service的使用背景
什么是service?
Service(服务)是一个一种可以在
后台执行长时间运行操作
而没有用户界面的应用组件。
服务分为两种形式:
非绑定状态
与绑定状态
。非绑定状态的时候
,activity启动服务以后,服务即可在后台无限期运行,即使activity已被销毁也不受影响
,除非手动调用才能停止服务。绑定状态
,activity与service进行了绑定,当activity销毁的时候,service也会被销毁
。
service的demo使用
// 在配置文件的配置
<service android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:isolatedProcess=["true" | "false"]
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
. . .
</service>
-
android:exported:代表是否能被其他应用隐式调用,其默认值是由service中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。为false的情况下,即使有intent-filter匹配,也无法打开,即无法被其他应用隐式调用。
-
android:name:对应Service类名
-
android:permission:是权限声明
-
android:process:是否需要在单独的进程中运行,当设置为android:process=”:remote”时,代表Service在单独的进程中运行。注意“:”很重要,它的意思是指要在当前进程名称前面附加上当前的包名,所以“remote”和”:remote”不是同一个意思,前者的进程名称为:remote,而后者的进程名称为:App-packageName:remote。
-
android:isolatedProcess :设置 true 意味着,服务会在一个特殊的进程下运行,这个进程与系统其他进程分开且没有自己的权限。与其通信的唯一途径是通过服务的API(bind and start)。
-
android:enabled:是否可以被系统实例化,默认为 true因为父标签 也有 enable 属性,所以必须两个都为默认值 true 的情况下服务才会被激活,否则不会激活。
// 未绑定的service写法:
// 第一步:添加配置文件的配置
<service
android:enabled="true"
android:name=".SimpleService" />
package com.zejian.ipctest.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
/**
* 第二步:实现service,并重写方法
*/
public class SimpleService extends Service {
/**
* 绑定服务时才会调用
* 必须要实现的方法
* @param intent
* @return
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)。
* 如果服务已在运行,则不会调用此方法。该方法只被调用一次
*/
@Override
public void onCreate() {
System.out.println("onCreate invoke");
super.onCreate();
}
/**
* 每次通过startService()方法启动Service时都会被回调。
* @param intent
* @param flags
* @param startId
* @return
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommand invoke");
return super.onStartCommand(intent, flags, startId);
}
/**
* 服务销毁时的回调
*/
@Override
public void onDestroy() {
System.out.println("onDestroy invoke");
super.onDestroy();
}
}
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* 第二步:在activity中调用service。
*/
public class ServiceActivity extends Activity implements OnClickListener{
Button buttonOn, buttonOff;
String TAG = "ServiceActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonOn = (Button) findViewById(R.id.button_on);
buttonOff = (Button) findViewById(R.id.button_off);
buttonOn.setOnClickListener(this);
buttonOff.setOnClickListener(this);
Log.v(TAG, "ActivityonCreate");
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case (R.id.button_on):
Log.v(TAG, "ActivitystartService");
this.startService(new Intent(this,SimpleService.class));
// startService(new Intent(this, SimpleService.class));
break;
case (R.id.button_off):
Log.v(TAG, "ActivitystopService");
this.stopService(new Intent(this,SimpleService.class));
//stopService(new Intent(this, SimpleService.class));
break;
default:
break;
}
}
@Override
protected void onStop() {
super.onStop();
Log.v(TAG, "ActivityonStop");
}
@Override
protected void onDestroy() {
Log.v(TAG, "ActivityonDestroy");
super.onDestroy();
}
}
// 绑定service的用法:
package com.zejian.ipctest.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* Description:绑定服务简单实例--服务端
*/
public class LocalService extends Service{
private final static String TAG = "wzj";
private int count;
private boolean quit;
private Thread thread;
private LocalBinder binder = new LocalBinder();
/**
* 创建Binder对象,返回给客户端即Activity使用,提供数据交换的接口
*/
public class LocalBinder extends Binder {
// 声明一个方法,getService。(提供给客户端调用)
LocalService getService() {
// 返回当前对象LocalService,这样我们就可在客户端端调用Service的公共方法了
return LocalService.this;
}
}
/**
* 把Binder类返回给客户端
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service is invoke Created");
thread = new Thread(new Runnable() {
@Override
public void run() {
// 每间隔一秒count加1 ,直到quit为true。
while (!quit) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
});
thread.start();
}
/**
* 公共方法
* @return
*/
public int getCount(){
return count;
}
/**
* 解除绑定时调用
* @return
*/
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "Service is invoke onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.i(TAG, "Service is invoke Destroyed");
this.quit = true;
super.onDestroy();
}
}
package com.zejian.ipctest.service;
import android.app.Activity;
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 com.zejian.ipctest.R;
/**
* Created by zejian
* Time 2016/10/2.
* Description:绑定服务实例--客户端
*/
public class BindActivity extends Activity {
protected static final String TAG = "wzj";
Button btnBind;
Button btnUnBind;
Button btnGetDatas;
/**
* ServiceConnection代表与服务的连接,它只有两个方法,
* onServiceConnected和onServiceDisconnected,
* 前者是在操作者在连接一个服务成功时被调用,而后者是在服务崩溃或被杀死导致的连接中断时被调用
*/
private ServiceConnection conn;
private LocalService mService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bind);
btnBind = (Button) findViewById(R.id.BindService);
btnUnBind = (Button) findViewById(R.id.unBindService);
btnGetDatas = (Button) findViewById(R.id.getServiceDatas);
//创建绑定对象
final Intent intent = new Intent(this, LocalService.class);
// 开启绑定
btnBind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "绑定调用:bindService");
//调用绑定方法
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
});
// 解除绑定
btnUnBind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "解除绑定调用:unbindService");
// 解除绑定
if(mService!=null) {
mService = null;
unbindService(conn);
}
}
});
// 获取数据
btnGetDatas.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mService != null) {
// 通过绑定服务传递的Binder对象,获取Service暴露出来的数据
Log.d(TAG, "从服务端获取数据:" + mService.getCount());
} else {
Log.d(TAG, "还没绑定呢,先绑定,无法从服务端获取数据");
}
}
});
conn = new ServiceConnection() {
/**
* 与服务器端交互的接口方法 绑定服务的时候被回调,在这个方法获取绑定Service传递过来的IBinder对象,
* 通过这个IBinder对象,实现宿主和Service的交互。
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "绑定成功调用:onServiceConnected");
// 获取Binder
LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
mService = binder.getService();
}
/**
* 当取消绑定的时候被回调。但正常情况下是不被调用的,它的调用时机是当Service服务被意外销毁时,
* 例如内存的资源不足时这个方法才被自动调用。
*/
@Override
public void onServiceDisconnected(ComponentName name) {
mService=null;
}
};
}
}
Service的种类
前台service的使用背景
在做手机音乐播放器的时候,有一件事就是手机有清理内存的软件,比如百度,360等等,一点击清理音乐就停止播放了,去后台查看发现Service已经被停止并重新启动了,这显然不是我想要的,我希望音乐能够在后台播放,并且自己能控制什么时候退出,不想让系统给我清理了,就像酷狗一直在通知栏显示那样,于是我就知道了在前台运行的服务。
参考:http://blog.itpub.net/70008155/viewspace-2809902/
https://blog.csdn.net/qq_45994879/article/details/127516406
https://community.modelscope.cn/63a01ebfdacf622b8df9162f.html?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-1-52709857-blog-105719010.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-1-52709857-blog-105719010.pc_relevant_vip_default&utm_relevant_index=1
https://blog.csdn.net/m1751250104/article/details/123695795
https://blog.csdn.net/qq_51986572/article/details/127855273