Service简单学习

来源:互联网 发布:mysql linux启动 编辑:程序博客网 时间:2024/06/06 01:09
  • 第一:什么是Service?
    Service是四大组件之一,Service与Activity相似,我们知道什么是Activitiy就好容易理解什么是Service,Service与Activity最大区别就在于Activity是负责与用户交互的,有界面,用户可视,而Service是没有用户界面的,位于后台,为整个程序提供服务的。Service与Activity都是Context派生出来的,因此也可以调用Context的方法。

  • 第二:创建与配置Service
    (1)创建一个继承自Service的类,实现父类的几个方法
    (2)在AndroidMenifest中使用service标签声明

  • 第三:
    了解Service的生命周期,使用startService()与bindService()启动的Service生命周期不一样,简单的画了个图

Service两种启动方式,生命周期对比

从图中可以看出,startService中在onCreate之后进入到onStartCommand就开始运行,相关逻辑就在onCreate和onStartCommand方法中操作,bindService中在onCreate之后,还会走onBind方法,进入onBind()方法,Service开始运行,相关逻辑代码,在onBind方法中编写,当用户点击退出服务时,即调用了unBind方法,之后
会走onDestory方法,

自己编写了一个简单的启动Service的程序,什么操作也没有,仅仅在生命周期中打印了几条日志
启动服务界面代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {    Button bind, unBind;    Intent intent;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        bind = (Button) findViewById(R.id.bind);        unBind = (Button) findViewById(R.id.unbind);        bind.setOnClickListener(this);        unBind.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.bind:                 intent=new Intent(MainActivity.this,MyService.class);                startService(intent);                break;            case R.id.unbind:                stopService(intent);                break;        }    }}

Service类代码:

public class MyService extends Service{    @Nullable    @Override    public IBinder onBind(Intent intent) {      Log.d("MyService", "onBind");        return null;    }    @Override    public void onCreate() {        super.onCreate();        Log.d("MyService", "onCreate");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.d("MyService", "onStartCommand");        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        super.onDestroy();        Log.d("MyService", "onDestroy");    }}

代码很简单,主界面是两个按钮一个start 一个stop
当点击一次start时,日志中输出了oncreat和onstartCommand,当点击三次时,输出一次onCreate三次onstartCommand
如图
第一次启动

也就是只有在第一次启动时会走onCreate,其他时候每次启动只会回调onstartCommand,不会回调onCreate,除非程序结束再次启动。当我点击stop时,走了onDestory,再次点击start才又走了onCreate,
第二次启动

注:代码中不要受我Button命名的影响,我是和bindService共用xml所以命了bind与unbind的名,实际上这里应该是start与stop才合适。
- 第四: Service的启动
启动Service的方法有两种
一种是通过Context的startService()方法,一种是Context的bindService方法
这两种方法的差异就是,startService()方法,访问者与Service之间几乎没有关联,即使访问者退出了,Service仍然运行,因此,Service与访问者之间也不能进行通信和数据的交换tService()方法启动,而bindService方法访问者与Service关联在一起,访问者退出,Service也退出,两者之间也可以进行相互通信,至于如何通信,后面来记。

这里有一条必须注意:Android5.0后要求必须使用显示Intent启动服务组件。

  • 第五:绑定本地Service并与之通信
    第四步已经说了通过startService启动的服务与访问者几乎没有关联,两者之间也不能进行通信与数据交换,要实现通信和数据交换应该通过bindService启动,bindService的
    完整标签为:bindService(Intent service, ServiceConnection conn,
    int flags)
    参数解释:
    参数1:service为要启动的service对象
    参数2:conn是一个ServiceConnection 对象,该对象用于监听service与Activity的连接状态,连接成功回调onServiceConnected(ComponentName name, IBinder service)方法,连接失败调用onServiceDisconnected(ComponentName name) 方法,这里需要注意,onServiceDisconnected方法是连接失败时回调的方法,如果是访问者自己解绑是不会回调这个方法的,而是执行unbindService(ServiceConnection conn) 。
    参数3:flags指定如果service还没有创建,是否自动创建,

注意到onServiceConnected(ComponentName name, IBinder service)这个方法中有一个IBinder 参数,这个参数就是Service类中IBinder onBind(Intent intent)返回的对象,可以通过这个对象实现Activitiy与Service的通信与数据交换。
下面这个小程序就是实现onBind方法并返回一个有效的IBind对象,

相关代码如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="match_parent"              android:layout_height="match_parent"              android:orientation="vertical">    <Button        android:id="@+id/bind"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="绑定服务"/>    <Button        android:id="@+id/unbind"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="解绑服务"/>    <Button        android:id="@+id/state"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="获取连接状态"/></LinearLayout>

布局文件是三个按钮分别为,绑定服务解绑服务和获取服务状态

Service类相关代码

public class MyService_bind extends Service {    private int count;    private boolean quit;    private MyBinder mMyBinder = new MyBinder();    @Nullable    @Override    public IBinder onBind(Intent intent) {        System.out.println("service is binded");        return mMyBinder;    }    @Override    public void onCreate() {        System.out.println("Service is  created");        //启动一个线程,用来动态改变count的值        new Thread() {            @Override            public void run() {                while (!quit) {                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                    }                    count++;                }            }        }.start();    }    //service断开连接时回调的方法    @Override    public boolean onUnbind(Intent intent) {        System.out.println(" service is unbind");        return true;    }    @Override    public void onDestroy() {        this.quit = true;        System.out.println("service is destory");    }    //实际开发中会使用继承自Binder的方式实现自己的IBinder对象,    public class MyBinder extends Binder {        public int getCount() {            return count;        }    }}

主界面相关代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {    Button bind, unBind, state;    Intent intent;    MyService_bind.MyBinder mMyBinder;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_bind);        bind = (Button) findViewById(R.id.bind);        unBind = (Button) findViewById(R.id.unbind);        state = (Button) findViewById(R.id.state);        state.setOnClickListener(this);        bind.setOnClickListener(this);        unBind.setOnClickListener(this);    }    //    private ServiceConnection mServiceConnection = new ServiceConnection() {        //Activity与Service连接成功回调的方法        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            System.out.println("Service  is  connected");            //赋值,强转。            mMyBinder = (MyService_bind.MyBinder) service;        }        //Activity与Service连接失败回调的方法,如果是访问者自动解绑,不会调用这个方法        @Override        public void onServiceDisconnected(ComponentName name) {            //            System.out.println("Service is disconnect");        }    };    @Override    public void onClick(View v) {        intent = new Intent(MainActivity.this, MyService_bind.class);        switch (v.getId()) {            case R.id.bind:                bindService(intent, mServiceConnection, BIND_AUTO_CREATE);                break;            case R.id.unbind:                unbindService(mServiceConnection);                break;            case R.id.state:                Log.i("chen","Service的count值    为"+mMyBinder.getCount());                break;        }    }}

运行程序,点击绑定服务
输出如下第一次点击链接成功
既然链接成功了,再来获取数据,点击第三个按钮,输出如下
取值

多次点击取值,看到输出count按照程序连续加一
然后点击解绑
解绑输出

输出unbind和destroy

在解绑后我再次点击获取值,输出的任意count值,并且不变都是66,这个时候点击绑定—>取值就会看到再次服务重新创建并且连接成功,输出不断增加的count值
这里写图片描述

简单的程序就到这里,实际开发中可以让MyBinder去操作Service中的更多数据,取决于业务需求。

bindService与startService还有一点不同的是无论点击多少次bindService都只会绑定一次,二startService多次点击却是会多次调用onstartCommand启动多次。

最近在看android讲义,用博客把知识梳理了一遍,增强了理解,目前先了解这么多,实际还要在开发中多多运用才能更好地掌握,下一次了解IntentService的使用,。

本人管理了一个群,这个群创建不久,现在人数也不多,希望有意一起交流技术的朋友们加群一起交流,让群越来越活跃,群内人员互相学习越来越厉害:群号: 361629723

0 0
原创粉丝点击