Service总结

来源:互联网 发布:do是java关键字 编辑:程序博客网 时间:2024/06/06 05:33

服务

  • 就是默默运行在后台的组件,可以理解为是没有前台的activity,适合用来运行不需要前台界面的代码
  • 服务可以被手动关闭,不会重启,但是如果被自动关闭,内存充足就会重启

下载代码和播放音乐这种运行于后台的代码,必须要写在服务里面。

为什么呢?例如下载:

activity 其实也是可以在后台下载,但是,点返回键的时候,activity死掉了(activity被onDestory()不代表该APP进程会被销毁),进程还在,那么子线程就依然可以下载,但当进程被销毁的时候,下载就会中断了。那进程什么时候销毁呢?在内存不足的时候进程就会很有可能被销毁…这时候就会涉及到进程优先级的知识。

进程优先级

  1. 前台进程:拥有前台activity(onResume方法被调用)
  2. 可见进程:拥有可见activity(onPause方法被调用)
  3. 服务进程:不到万不得已不会被回收,而且即便被回收,内存充足时也会被重启
  4. 后台进程:拥有后台activity(activity的onStop方法被调用了),很容易被回收
  5. 空进程:没有运行任何activity,很容易被回收

服务:开启方式

1.Context.startService()

  • (重点)该方法启动的服务所在的进程属于服务进程
  • Activity一旦启动服务,服务就跟Activity一毛钱关系也没有了
  • 不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。

  • 在需要开启服务的Activity中:

Intent intent = new Intent(this, MyService.class);startService(intent);//开启stopService(intent);//关闭

2.Context.bindService()

  • (重点)该方法启动的服务所在进程不属于服务进程
  • Activity与服务建立连接,Activity一旦死亡,服务也会死亡

*在需要开启服务的Activity中:

Intent intent = new Intent(this, MyService.class);    MyServiceConn conn = new MyServiceConn();    bindService(intent, conn, BIND_AUTO_CREATE);    class MyServiceConn implements ServiceConnection{  //内部类,服务链接对象    //连接服务成功,此方法调用    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        // TODO Auto-generated method stub        pb = (PublicBusiness) service;    }    @Override    public void onServiceDisconnected(ComponentName name) {        // TODO Auto-generated method stub    }}

MyService类内容:

public class MyService extends Service {    //绑定时调用    @Override    public IBinder onBind(Intent intent) {        // TODO Auto-generated method stub        System.out.println("bind方法");        return null;    }    //解绑时调用    @Override    public boolean onUnbind(Intent intent) {        // TODO Auto-generated method stub        System.out.println("unbind方法");        return super.onUnbind(intent);    }    @Override    public void onCreate() {        // TODO Auto-generated method stub        super.onCreate();        System.out.println("create方法");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        // TODO Auto-generated method stub        System.out.println("start方法");        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        // TODO Auto-generated method stub        System.out.println("destroy方法");        super.onDestroy();    }}

生命周期

1.ContextstartService启动服务的生命周期

onCreate()->onStartCommand()->onDestroy()
  • 重复的调用Context.startService()会导致onStartCommand()被重复调用,而onCreate()只会被调用一次

2.Context.bindService()绑定服务的生命周期

onCreate()->onBind()->onUnbind() -> onDestroy() 
  • 重复的调用Context.bindService(),只会走一次onCreate()->onBind()。同时也不能重复地解绑,启动后,只能解绑一次。

服务的混合调用(重点)

  • 先startService()、再bindService(),先解绑、再停止,比如:用服务实现音乐播放时,因为音乐播放必须运行在服务进程中,可是音乐服务中的方法,需要被前台Activity所调用,所以需要混合启动音乐服务先start,再bind,销毁时先unbind,再stop

onCreate()->onStartCommand()->onBind()->onUnbind()-> onDestroy() 

服务运行在主线程

 Service和其他的应用组件一样,运行在进程的主线程中。这就是说如果service需要很多耗时或者阻塞的操作,需要在其子线程中实现。

找领导办证(访问服务里面的方法)

  • 把服务看成一个领导,服务中有一个banZheng方法,如何才能访问?
  • 绑定服务时,会触发服务的onBind方法,此方法会返回一个Ibinder的对象给MainActivity,通过这个对象访问服务中的方法

  • 在服务中定义一个类实现Ibinder接口,以在onBind方法中返回

class ZhongJianRen extends Binder implements PublicBusiness{public void QianXian(){    //访问服务中的banZheng方法    BanZheng();}   public void daMaJiang(){}}

public class MainActivity extends Activity {    private Intent intent;    private MyServiceConn conn;    PublicBusiness pb;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        intent = new Intent(this, LeaderService.class);        //绑定服务时要求传入一个ServiceConnection实现类的对象        conn = new MyServiceConn();        //1.绑定领导服务        bindService(intent, conn, BIND_AUTO_CREATE);    }//2.内部类,服务链接对象    class MyServiceConn implements ServiceConnection{        //连接服务成功,此方法调用        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            //5. TODO Auto-generated method stub            pb = (PublicBusiness) service;        }        @Override        public void onServiceDisconnected(ComponentName name) {            // TODO Auto-generated method stub        }    }    public void click(View v){        //调用服务的办证方法        pb.QianXian();    }}
LeaderService服务类:
public class LeaderService extends Service {        @Override        public IBinder onBind(Intent intent) {            //3. 返回一个Binder对象,这个对象就是中间人对象            return new ZhouMi();        }    //4.在服务中定义一个类实现Ibinder接口,以在onBind方法中返回    class ZhouMi extends Binder implements PublicBusiness{        public void QianXian(){                banZheng();            }        public  void daMaJiang(){                System.out.println("陪李处打麻将");            }        }        public void banZheng(){            System.out.println("李处帮你来办证");        }    }
把QianXian方法抽取到接口PublicBusiness中定义
public interface PublicBusiness {        void QianXian();    }

服务的分类

  • 本地服务:指的是服务和启动服务的activity在同一个进程中
  • 远程服务:指的是服务和启动服务的activity不在同一个进程中

AIDL

  • Android interface definition language
  • 进程间通信
    1. 把远程服务的方法抽取成一个单独的接口java文件
    2. 把接口java文件的后缀名改成aidl
    3. 在自动生成的PublicBusiness.java文件中,有一个静态抽象类Stub,它已经继承了binder类,实现了publicBusiness接口,这个类就是新的中间人(继承的时候直接:中间人类名Stub)
    4. 把aidl文件复制粘贴到06项目,粘贴的时候注意,aidl文件所在的包名必须跟05项目中aidl所在的包名一致
    5. 在06项目中,ServiceConnection对象链接类中的onServiceConnected()方法中强转中间人对象得到中间人对象:mService = IMusicService.Stub.asInterface(serviceIBinder);





0 0