android学习之Service
服务是安卓中的典型组件,一般组件都需要在清单文件中注册。服务能够长时间的运行在后台,并且不提供用户界面。其他的组件能够开启服务 并且在用户在开启其他应用的时候该服务仍然能够继续在后台执行。一个组件通过bind的方式绑定服务,并且该组件能与之交互。
最典型的案列就是播放音乐,播放器应用在后台仍然能够播放音乐。
服务,简单的解释就是,长期在后台运行并且没有界面的组件。类似天气预报和股票显示的应用,需要在后台连接服务器,
每隔一段时间,获取最新的数据。Service不需要在activity中开启子线程。
服务有两种开启方式:
第一种:采用start的方式开启服务
Intent intent = new Intent(this,MyService.class); startService(intent);
这种方式类似于Activity的创建,通过Intent来实现,同时停止服务和开启服务类似:
Intent intent = new Intent(this,MyService.class); stopService(intent);
用这种方式创建Service的生命周期如下:onCreate()--> onStartCommand() ---> onDestory(),有一个onStart()的过时的方法,需要服务处理的逻辑一般在onStartCommand和onStart里面执行。这里需要注意的几点:
一、如果服务重复开启,当再次执行startService方法时,不再执行onCreate方法,而是直接执行onStartCommand方法;
二、服务停止的时候,显然会执行onDestory方法,并且只会执行一次该方法,重复调用stopService方法时没用的。
这种方式开启服务的特点:采用start方式开启的服务。一旦服务开启了,就和开启者没有关系,这时候开启者(一般是Activity组件)
被销毁后,服务仍然在后台执行;这种方式开启的服务还有一个缺点就是开启者无法调用服务内部的方法,也就是无
法与服务进行交互。
第二种:采用bind的方式开启服务
采用这种bind的方式开启服务主要是为了能够调用Service中的方法,那么如何通过绑定服务的方式来调用服务里面的方法呢?
可以分成5个步骤:
一、首先Service中要暴露出方法,定义一个内部类,这个内部类相当于中介,由中介这个内部成员来帮我们干活,即调用
Service内部的方法。
二、继承Service默认有一个方法onBind,通过这个onBind将中介的信息传递出去,也就是返回一个new 出来的中介
对象,而且onBind的返回值是IBinder,而这个中介必须是IBinder类型,所以中介这个内部类需要继承Binder类或实
现IBinder接口。
三、定义一个内部类实现ServiceConnection接口来获得中介对象,以便能够调用Service里面的方法。
三个参数,第一个是一个意图,第二个是ServiceConnection,这是一个接口,通过这个接口可以获得第二步
中onBind方法返回的中介对象,所以这里需要我们去实现这个接口。第三个参数表示绑定服务的操作,
比如BIND_AUTO_CREATE-->表示绑定的时候自动创建服务。
五、通过中介调用Service里面的方法。
这就是以上五个步骤。
这种方式开启服务时服务的生命周期:
onCreate() --->onBind();--->onunbind()-->onDestory();
绑定服务不会调用onstart或者onstartcommand方法;
下面是第二种方式开启的服务的部分代码:
package com.example.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; public class MyService extends Service { public MyService() { } @Override //2、返回中介对象 public IBinder onBind(Intent intent) { return new Agency(); } @Override public void onCreate() { System.out.println("服务onCreate"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("服务onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { System.out.println("服务onDestory"); super.onDestroy(); } public void methodInService() { System.out.println("服务里的方法被执行"); } /** * 1、中间人,相当于调用者Activity和Service之间的桥梁 */ private class Agency extends Binder implements IAgency{ public void callMethodInService(int money) { if(money>50) { methodInService(); } else { System.out.println("钱不够,不给干活。。。。"); } } } }
package com.example.service; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.View; public class MainActivity extends Activity { private IAgency agency; private MyConn conn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //4、以bind的方式开启服务 public void bind(View view) { Intent intent = new Intent(this,MyService.class); conn = new MyConn(); bindService(intent, conn, BIND_AUTO_CREATE); } public void unbind(View view) { unbindService(conn); } //5、通过中介来调用方法 public void call(View view) { agency.callMethodInService(55); } @Override protected void onDestroy() { System.out.println("Activity 被销毁"); super.onDestroy(); } //3、通过实现ServiceConnection来获得中介对象 private class MyConn implements ServiceConnection { @Override //当服务连接的时候或者被成功绑定的时候调用 public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("在Activity中成功得到了中间人。。。"); agency = (IAgency) service; } @Override //当服务失去连接的时候调用,(一般进程挂了,服务被异常终止) public void onServiceDisconnected(ComponentName name) { } } }还有一个地方需要注意:就是在服务被解除的时候,将调用onDestory方法,Service被销毁,但是Service中的内部类也就是中介并没有被销毁,所以一般在调用unbindService方法之后,一般会将中介对象置为null。
最后附上Android api中的service生命周期图: