Fork me on GitHub

Service的入门讲解

简介:Service作为Android四大组件之一,与Activity的地位是并列的,不同的是Service主要位于后台执行长时间的操作,(ep:一个Service可以在后台执行网络请求、播放音乐、执行文件读写操作)一般不需要与用户交互,也就不用依赖于UI界面。However,Service一旦启动也就具有了生命周期,用法和Activity类似。

—注意:Service和线程是两个不同的概念。Servie是系统的组件,而Thread是程序执行的最小单元。而且Service是运行在主线程里的,所以为了不出现ANR可以在服务里创建一个线程来处理复杂耗时的任务。在服务里创建线程是为了方便控制。

Service的创建、注册

  • 定义一个继承Service的子类:
    主要重写其中的4个方法:onBind()方法用于Activity和Service之间的通信,onCreate()方法会在服务创建的时候调用,onStartCommand()方法会在每次服务启动的时候调用,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
    public class MyService extends Service {
    public static final String TAG = "MyService";
    @Override
    public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreate()");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
    Log.d(TAG, "onStartCommand()");
    return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroy() ");
    }
    @Override
    public IBinder onBind(Intent intent) {
    return null;
    }
    }
  • 在AndroidManifest.xml中注册:
    和activity类似,需要注册才能生效。
    <service android:name=".MyService" ></service>

Service的生命周期

  • Service的启动方式
    有两种:Context.startService和Context.bindService()
    (1)started:通过startService()启动的服务处于“启动的”状态,一旦启动,service就在后台运行,无论启动它的应用组件是否已经被销毁。通常started状态的service执行单任务并且不返回任何结果给启动者。比如当下载或上传一个文件,当这项操作完成时,可以通过stopSelf()或者stopService()来停止。
    (2)bound:通过调用bindService()来启动,一个绑定的service提供一个允许组件与service交互的接口,可以发送请求、获取返回结果,还可以通过跨进程通信来交互(IPC)。绑定的service只有当应用组件绑定后才能运行,多个组件可以绑定一个service,当所有组件调用unbind()方法时,这个service就会被销毁了。
    这两种方法并不完全分开,可以交叉使用,比如说通过startService()启动服务后也可以通过bindService()来实现绑定。但这种服务的销毁就要调用onUnbind方法。
  • 生命周期
    启动方式不同

从图中可以看出,Service和Activity一样,都是从oncreate()开始到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
public class MainActivity extends AppCompatActivity {
private Button button1;
private Button button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1= (Button) findViewById(R.id.b_start);
button2= (Button) findViewById(R.id.b_stop);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,MyService.class);
startService(intent);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,MyService.class);
stopService(intent);
}
});
}
}

活动与服务

活动与服务间的通信是通过bindservice(Intent service,ServiceConnection coon,int flags)来实现的,首先我们得创建一个匿名类获取到ServiceConnection,然后重写里面的onServiceConnected()方法和onServiceDisconnected()方法,可以处理活动与服务成功绑定时的任务。比如我们可以得到服务里Binder的实例,通过这个实例,就可以在activity中去控制服务。
/Mainactivity/

private ServiceConnection serviceConnection=new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder ibinder) {
        mybinder= (MyService.mybinder) ibinder;
        mybinder.pr();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
};
    ....//其他操作
    button3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent=new Intent(MainActivity.this,MyService.class);
            bindService(intent,serviceConnection,BIND_AUTO_CREATE);

        }
    });
    button4.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            unbindService(serviceConnection);
        }
    });

/MyService/

private mybinder mybinder=new mybinder();
class mybinder extends Binder{
    public void pr(){
        Log.d(TAG,"onBind()");
    }
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return mybinder;
}