Service之简单使用

时间:2022-06-06 05:29:36

生命周期

Service之简单使用

context.startService() ->onCreate()- >onStartCommand()->Service running--调用context.stopService() ->onDestroy() 

context.bindService()->onCreate()->onBind()->Service running--调用>onUnbind() -> onDestroy()

基础知识

服务一般分为两种:

  1. 本地服务, Local Service 用于应用程序内部。在Service可以调用Context.startService()启动,调用Context.stopService()结束。 在内部可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。无论调用了多少次startService(),都只需调用一次 stopService()来停止。

  2. 远程服务, Remote Service 用于android系统内部的应用程序之间。可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服 务。调用Context.bindService()方法建立连接,并启动,以调用 Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加 载它。提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可。

注意事项

同一服务,多次启动,服务实际执行的过程:

第一次 启动服务时,运行 onCreate –>onStartCommand

后面在启动服务时,服务只执行onStartCommand

在实际使用过程中,通过Intent 传递数据,在OnStartCommand中执行。

建议用onStartCommand

查看google 文档

http://developer.android.com/reference/android/app/Service.html

onStart(Intent intent, int startId)

This method was deprecated in API level 5. Implement onStartCommand(Intent, int, int) instead.

onStartCommand(Intent intent, int flags, int startId)

Called by the system every time a client explicitly starts the service by calling startService(Intent), providing the arguments it supplied and a unique integer token representing the start request.
鉴于目前的代码基本都是运行在API5 以上的,所以直接干掉onStart.

服务的类型

按照使用范围分类:

1、本地服务(Local Service):用于应用程序内部

功能:用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。

使用:在Service可以调用Context.startService()启动,调用Context.stopService()结束。在内部可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。无论调用了多少次startService(),都只需调用一次stopService()来停止。

2、远程服务(Remote Sercie):用于android系统内部的应用程序之间

功能:可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。

使用:可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服务。调用Context.bindService()方法建立连接,并启动,以调用 Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。

按照运行类别分类分:

1、前台服务

前台服务需要调用 startForeground ( android 2.0 及其以后版本 )或 setForeground (android 2.0 以前的版本)使服务成为 前台服务。
使用前台服务可以避免服务在后台运行的时候被系统KILL。

使用:可以看出,我们只需要在onStartCommand里面调用 startForeground方法让服务前台运行,然后再onDestroy里面调用stopForeground解除前台运行既可!
所以,例如手机中的音乐播放器,不管手机是否是在休眠状态,只要开始播放了,系统就不会去KILL这个服务,只有当停止播放音乐时,服务才可能会回收清除。

2、后台服务

后台服务就是处于后台运行的

注意:本地服务中,onStart已经被onStartCommand方法取代,Service和Activity都是由Context类派生的,可以通过getApplicationContext()方法获取上下文对象,和Activity一样,它有着自己的生命周期,可是和Activity相比,它所执行的过程略有不同,如上图所示。

在服务分类中,提到了3种服务通信类型,一种是通过startService()直接启动服务,一种是通过bindService()的方式启动,2种启动方式对应的生命周期如上图所示。3.使用AIDL方式的Service( AIDL解析(一)两个应用之间使用AIDL进行通信的例子AIDL解析(二 )让Service主动调起Activity吧!

简单使用,使用广播和接口的两种不同方式传递消息

Service之简单使用

开启服务

Service之简单使用

停止服务

Service之简单使用

绑定服务

Service之简单使用

解绑服务

Service之简单使用

互发消息

Service之简单使用

ServiceActivity

package com.bourne.android_common.ServiceDemo;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ProgressBar;

import com.bourne.android_common.R;
import com.bourne.common_library.utils.Logout;

public class ServiceActivity extends AppCompatActivity {

MyConn conn;
Intent intent;
MyService.IService iService;
MyService myService;
private LocalBroadcastManager mLocalBroadcastManager;
private MyBroadcastReceiver mBroadcastReceiver;
public final static String ACTION_TYPE_MYSERVICE= "action.type.myservice";

private int progress = 0;
private ProgressBar mProgressBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);

//注册广播
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_TYPE_MYSERVICE);
mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);

mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
}

/**
* 启动服务
*
* @param view
*/

public void start(View view) {
intent = new Intent(ServiceActivity.this, MyService.class);
startService(intent);
}

/**
* 停止服务
*/

public void stop(View view) {
stopService(intent);
}

/**
* 绑定服务
*/

public void bind(View view) {
conn = new MyConn();
intent = new Intent(ServiceActivity.this, MyService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
}

/**
* 绑定服务
*/

public void unbind(View view) {
unbindService(conn);
}

/**
* 使用广播方式发送消息
*/

public void brocast(View view) {
iService.callMethodInService();
}

/**
* 连接Service
*/

private class MyConn implements ServiceConnection {

//使用广播方式
iService = (MyService.IService) service;

//使用接口方式
myService = ((MyService.MyBinder)service).getService();
//注册回调接口来接收下载进度的变化
myService.setOnProgressListener(new MyService.OnProgressListener() {

@Override
public void onProgress(int progress) {
mProgressBar.setProgress(progress);

}
});
}

public void onServiceDisconnected(ComponentName name) {

}

}

/**
* 使用广播方式接受Sercice的消息
*/

public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {

case ACTION_TYPE_MYSERVICE:
Logout.e("Activity收到来自Service的消息");
break;
}
}
}


/**
* 使用接口方式发送消息
*/

public void listener(View view) {
//开始下载
myService.startDownLoad();
}
}

MyService

package com.bourne.android_common.ServiceDemo;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;

import com.bourne.common_library.utils.Logout;

public class MyService extends Service {

public interface IService {
void callMethodInService();
}

public class MyBinder extends Binder implements IService {

public void callMethodInService() {
helloInservice();
}

/**
* 获取当前Service的实例
* @return
*/

public MyService getService(){
return MyService.this;
}
}

/**
* 广播
*/

private LocalBroadcastManager mLocalBroadcastManager;

/**
* 发送消息
*/

private void sendBroadcast() {
Intent intent = new Intent(ServiceActivity.ACTION_TYPE_MYSERVICE);
mLocalBroadcastManager.sendBroadcast(intent);
}

public void helloInservice() {
Logout.e("service收到来自activity的消息");
sendBroadcast();
}

public MyService() {
Logout.e("MyService");
}

@Override
public void onStart(Intent intent, int startId) {
Logout.e("onStart");
super.onStart(intent, startId);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Logout.e("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onCreate() {
Logout.e("onCreate");
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
super.onCreate();

}

@Override
public void onDestroy() {
Logout.e("onDestroy");
super.onDestroy();

}

@Override
public IBinder onBind(Intent intent) {
Logout.e("onBind");
return new MyBinder();
}

@Override
public boolean onUnbind(Intent intent) {
Logout.e("onUnbind");
return super.onUnbind(intent);
}

public interface OnProgressListener {
void onProgress(int progress);
}
/**
* 进度条的最大值
*/

public static final int MAX_PROGRESS = 100;

/**
* 进度条的进度值
*/

private int progress = 0;

/**
* 更新进度的回调接口
*/

private OnProgressListener onProgressListener;


/**
* 注册回调接口的方法,供外部调用
* @param onProgressListener
*/

public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
}

/**
* 增加get()方法,供Activity调用
* @return 下载进度
*/

public int getProgress() {
return progress;
}

/**
* 模拟下载任务,每秒钟更新一次
*/

public void startDownLoad(){
new Thread(new Runnable() {

@Override
public void run() {
while(progress < MAX_PROGRESS){
progress += 5;

//进度发生变化通知调用方
if(onProgressListener != null){
onProgressListener.onProgress(progress);
}

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}).start();
}


}

AndroidManifest

     <service android:name=".ServiceDemo.MyService"></service>

参考