Android四大组件之Service

Service是与Activity最相似的组件,他们都代表可执行的程序,只是Service一直都是在后台运行,它没有用户界面,所以绝对不会到前台来,一旦Service被启动起来之后,它就像Activity一样拥有自己的生命周期,同样是从Context中派生而来的,因此也可以调用Context里定义的如getResources(),getContentResolver()等方法,如果不需要用户交互界面,我们可以考虑通过Service来实现。

创建一个Service的过程:
1.定义一个继承自Service的之类
2.在AndroidManifest.xml文件中配置该Service
我们来看一下具体的code:

/**
 * Service 启动Service的方式(Activity中):
 *      Intent service = new Intent(this,MyService.class);
        startService(service);
    第一次创建Service的时候会调用onCreate函数,然后调用onStartCommand函数
    每点击一次启动Service的时候都会调用onStartCommand函数
    停止Service的时候调用:stopService(service);这个函数会调用Service中的onDestory函数多次调用stopService只会触发一次onDestory
 * */
public class MyService extends Service {
    private boolean exit = false;
    private static int count = 0;
    @Override
    public IBinder onBind(Intent intent){
        System.out.println("onBind()");
        count = 0 ;//为了演示一下unbind之后再次绑定,我们清楚以前统计的值
        MyBinder myBinder= new MyBinder();
        return myBinder;
    }

    @Override
    public void onCreate() {
        System.out.println("onCreate()");
        super.onCreate();
        new Thread(new Runnable() {

            @Override
            public void run() {
                while(!exit){
                    try {
                        //1s增加一次count
                        Thread.sleep(1000);
                        count++;
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    @Override
    public void onDestroy() {
        System.out.println("onDestroy()");
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("onStartCommand()");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onRebind(Intent intent) {
        System.out.println("onRebind()");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("onUnbind()");
        exit = true;
        return true;
    }
    //我们可以通过传递binder对象来获取我们Service中的count值
    public class MyBinder  extends Binder{
        public int getCount(){
            return count;
        }
    }
}

我们必须实现public IBinder onBind(Intent intent){}这个是在我们bindService的时候用得到;

Service启动的两种方式:

一、startService(intent)启动解析:
这里我们可以通过打印得到其生命周期:
onCreate—–>onStartCommand—->Service停止—–>onDestory
这里我们需要注意的是:
1.onCreate函数只在启动Service的时候调用一次,
2.onStartCommand则是在调用startService的时候调用,且每次都会调用到这个函数
3.stopService(intent)点击多次只会调用一次onDestory
4.由于这里没有涉及到bind函数,因此这也叫非绑定性的Service
二、bindService()启动解析:
首先是其生命周期显示:
onCreate—->onBind—>解绑定Service—->onUnbind—>onDestory
这里我么需要注意的是:
1.我们没有调用onStartCommand函数,而是调用了onBind函数,并且多了一个onUnbind函数的调用
2.每次调用bindService的时候我们都会去调用onServiceConnected函数,这里类似上面的onStartCommand函数的调用
3.onDestory函数的调用是在onUnbind函数之后,但是我们需要注意的是并不是说onUnbind调用之后就一定要调用onDestory,当我们通过startService启动Service之后我们调用bindService之后调用onUnbind函数是不会触发调用onDestory的,因此这里不要理解错了!
4.Activity调用bindService绑定一个已启动的Service时,系统只是把Service内部的IBinder对象给了Activity(通过onServiceConnected中的IBinder service参数传递过来),并不会把该Service生命周期完全绑定到该Activity上,因此当调用unBindService的时候也只是切断了与Activity的联系,并不能停止该Service

通过第4点我们得到了还有一种Service的启动模式,也就是混合模式
通过startService启动然后绑定Service之后解绑之后stopService

onCreate—->onStartCommand—>onBind—>onUnbind—->onDestory
如果我们解绑之后再次点击绑定,我们会发现我们触发了 onRebind(前提是onUnBind方法返回true
因此此时过程变成了:
onCreate—->onStartCommand—>onBind—>onUnbind—->onRebind—>onUnbind—->onDestory

然后我们需要了解的是Binder 与Activity之间是怎么通信的,因此做了一个demo,在Activity中去获取Service中的一个static int count 变量,在onCreate中开一个线程不断增加这个变量的值,直到我们调用onUnbind函数
因此我们可以得到他们之间的关系是:

conn = new ServiceConnection() {

            @Override
            public void onServiceDisconnected(ComponentName name) {
                System.out.println("onServiceDisconnected");
            }
            //service是我们调用Service中的onBind方法返回来的一个Binder对象。通过这个对象我们就可以操作对象关联的函数了
            //我们多次点击BindService,只会调用一次Service中的onBind方法,但是会多次调用onServiceConnected方法
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                System.out.println("onServiceConnected");
                myBinder = (MyBinder) service;
                System.out.println("count = "+myBinder.getCount());
            }
        };

bindService(service, conn, Service.BIND_AUTO_CREATE);—–中的conn变量作为一个Service沟通的桥,里面我们获取了绑定Service之后由onBind函数返回的一个Binder对象,然后我们的Activity就可以通过这个对象获取Service中的count变量的值了,因此这样就实现了这两大组件之间的联系
下面看一下我们的布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="startService"
        android:text="startService" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="stopService"
        android:text="stopService" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="DoBindService"
        android:text="bindService" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="DoUnbindService"
        android:text="UnbindService" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getCount"
        android:text="getCount" />

</LinearLayout>

MainActivity中的对这些button的点击事件的反应:

public class MainActivity extends Activity {
    private Intent service ;
    private MyBinder myBinder;
    private ServiceConnection conn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        service = new Intent(this,MyService.class);
    }
    public void startService(View v)
    {
        startService(service);
    }

    public void stopService(View v)
    {
        stopService(service);
    }
    //bindService会调用onCreate 和  onBind
    public void DoBindService(View v)
    {
            conn = new ServiceConnection() {

            @Override
            public void onServiceDisconnected(ComponentName name) {
                System.out.println("onServiceDisconnected");
            }
            //service是我们调用Service中的onBind方法返回来的一个Binder对象。通过这个对象我们就可以操作对象关联的函数了
            //我们多次点击BindService,只会调用一次Service中的onBind方法,但是会多次调用onServiceConnected方法
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                System.out.println("onServiceConnected");
                myBinder = (MyBinder) service;
                System.out.println("count = "+myBinder.getCount());
            }
        };
        bindService(service, conn, Service.BIND_AUTO_CREATE);
    }

    public void getCount(View v){
        Toast.makeText(this, "count="+myBinder.getCount(), 0).show();
    }

    public void DoUnbindService(View v )
    {
        if(conn!=null){
            unbindService(conn);
            conn = null;
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值