8.安卓基础之service服务

1. service 服务

Service是一个应用程序组件,它能够在后台执行一些耗时较长的操作,并且不提供用户界面。服务能被其它应用程序的组件启动,即使用户切换到另外的应用时还能保持后台运行。此外,应用程序组件还能与服务绑定,并与服务进行交互,甚至能进行进程间通信(IPC)。 比如,服务可以处理网络传输、音乐播放、执行文件I/O、或者与content provider进行交互,所有这些都是后台进行的。

1.1 编写服务的步骤

  • 继承service类,那么就写 了一个服务
  • 到清单中进行配置
  • 启动服务,关闭服务

注意 :
直接开启服务,超时的事,会引发应用程序 ANR(application not responding) ,导致这种问题,是因为主线程中干了耗时的事情,service是运行在主线程中的,主线程是不允许干耗费时间的事儿.

1.2 为什么需要服务

android系统会尽可能的保持应用程序进程的一致存在,即是在应用退出后,也仍然这样.但是,如果发现内存不够用,需要去启动新的进程时,那么会按照顺序的优先级去杀死某些老的进程.

进程 : 就是一块独立的内存空间,用来运行程序.

android中进程的分类 :

  • 前台进程
    Forground process : 可以与用户直接进行交互,就是前台进程.
  • 可视进程
    Visible process : 可以看到,但是不能直接与用户进行交互.
  • 服务进程
    Service process : 进程中运行了一个服务,在运行着.
  • 后台进程
    Background process : 在一个activity,现在可以不见.但是在后台运行着.
  • 空进程
    Empty process : 一个进程中,没有服务,也没有activity,整个程序都已经退出.

重要级别 : 前台进程->可视进程->服务进程->后台进程->空进程

服务可以长期后台运行,是与当前启动服务的activity是没有关系的.

  • 先在清单注册服务

    1
    <service android:name=".QuickStartService"></service>
  • 继承一个服务类

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
/**
* Created by 诸葛亮 on 2016/12/10.
* Service : 实际上就是一个没有界面的activity
*/
public class QuickStartService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private boolean flag;
@Override
public void onCreate(){
super.onCreate();
System.out.print("onCreate服务被创建了:"+Thread.currentThread().getName());
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@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();
flag =false;
System.out.println("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
package com.javami.quickstartservice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//开启服务
public void start(View v){
Intent intent = new Intent();
intent.setClass(this,QuickStartService.class);
startService(intent);
}
//关闭服务
public void stop(View v){
Intent intent = new Intent();
intent.setClass(this,QuickStartService.class);
stopService(intent);
}
}

1.3 启动服务的生命周期

当点击开启服务,服务会创建,点击关闭服务后,服务会销毁.服务只会在第一次创建调用onCreate,多次开启服务,只会去重复调用onStartCommand,并不会去新创建服务.

所以,多次开启服务的方式,去调用服务中的方法是走不通的,调用不了服务中的方法.需要使用绑定服务去调用服务中的方法.

2. 绑定服务

bindService(service,conn,flags)

2.1 编写绑定服务调用服务中的方法的步骤 :

  • 第一步 : 在服务中去编写一个要被外面调用的方法
1
2
3
4
5
//服务中的方法
public void methodInService(String name,int money){
Toast.makeText(this,"服务中的方法被调用...",0).show();
}
  • 在服务中提供一个内线,这个内线是继承了Binder类,实现 IService接口
1
2
private class MyAgent extends Binder implements IService{
}
  • 编写一个IService接口,提供一个方法
1
2
3
4
public interface IService {
public void callMethodInService(String name,int money);
}
  • 进到服务内线中,在内线实现接口方法,调用服务中的方法
1
2
3
4
5
6
7
8
9
private class MyAgent extends Binder implements IService{
@Override
public void callMethodInService(String name, int money) {
//调用服务中的方法
methodInService(name,money);
}
}
  • 在onBind方法中,返回内线
1
2
3
4
5
@Override
public IBinder onBind(Intent intent) {
System.out.println("onBind执行了,绑定了服务");
return new MyAgent();
}
  • 回到百姓activity中,使用绑定服务的方式去开启服务的内线通讯频道,在通讯频道的ServiceConnection的实现类中的,onServiceConnected中拿到内线的引用.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyConn implements ServiceConnection {
//当成功绑定了服务,返回内线的引用的方法,用于返回内线的对象
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
agent = (IService) service;
System.out.println("服务绑定的时候执行了onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
agent = null;
System.out.println("服务绑定的时候执行了onServiceDisconnected");
}
}
  • 通过对内线的引用,去调用service中的方法
1
2
3
4
//调用服务中的方法
public void callMethodInService(View v){
agent.callMethodInService("kevin",10000);
}

2.2 绑定服务的声明周期

  • 绑定服务 : 调用oncreate,onbind方法
  • 解绑服务 : 调用onunbind方法,调用ondestroy方法服务销毁

2.3 混合开启服务的介绍

绑定服务可以调用服务中的方法,开启服务可以让服务在后台一直运行.
开启服务->绑定服务->调用服务中的方法->解绑服务->关闭服务

结论 :
如果以后需要去后台一直运行服务,而且又想调用服务中的方法,那么请按以上的过程走!

3. 总结

从前,一位想要办证的用户,需要直接到某部分办证.但是中国式办证太难.只能找到代理,因为代理里面有在政府上班的人,所以代理能利用一切关系来搞掂证件(从服务里面定义代理与方法),那么某用户找到内线(内线通过中间人IService找到),获得内线后.只是钱和事的问题了!