Service如何工作?

来源:互联网 发布:qq三国关羽打技能数据 编辑:程序博客网 时间:2024/05/21 14:57

Service 服务:

一个Service是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序。

比较好的一个例子就是一个正在从播放列表中播放歌曲的媒体播放器。在一个媒体播放器的应用中,应该会有多个activity,让使用者可以选择歌曲并播放歌曲。然而,音乐重放这个功能并没有对应的activity,因为使用者当然会认为在导航到其它屏幕时音乐应该还在播放的。

在这个例子中,媒体播放器这个activity会使用Context.startService()来启动一个service,从而可以在后台保持音乐的播放。同时,系统也将保持这个service一直执行,直到这个service运行结束。另外,我们还可以通过使用Context.bindService()方法,连接到一个service上(如果这个service还没有运行将启动它)。当连接到一个service之后,我们还可以使用service提供的接口与它进行通讯。拿媒体播放器这个例子来说,我们还可以进行暂停、重播等操作。

Service使用步骤如下

       1>继承service

       2>AndroidManifast.xml配置清单文件中<application>节点里对服务进行配置

              <service name=".SMSService"/>

服务不能自己运行,需要通过Contex.startService()Contex.bindService()启动服务

1.通过startService()方法启动的服务于调用者没有关系,即使调用者关闭了,服务仍然运行想停止服务要调用Context.stopService(),此时系统会调用onDestory(),使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onStart(),如果服务已经启动再次调用只会触发onStart()方法

2.使用bindService()启动的服务与调用者绑定,只要调用者关闭服务就终止,使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onBind(),如果服务已经启动再次调用不会再触发这2个方法,调用者退出时系统会调用服务的onUnbind()-->onDestory(),想主动解除绑定可使用Contex.unbindService(),系统依次调用onUnbind()-->onDestory();

Service服务生命周期

                                                           

Service完整的生命周期:从调用onCreate()开始直到调用onDestroy()结束

Service有两种使用方法:

1>以调用Context.startService()启动,而以调用Context.stopService()结束

2>以调用Context.bindService()方法建立,以调用Context.unbindService()关闭

service重要的生命周期方法

当用户调用startService()或bindService()时,Service第一次被实例化的时候系统会调用,整个生命周期只调用1次这个方法,通常用于初始化设置。

注意:多次调用startService()或bindService()方法不会多次触发onCreate()方法

void onCreate()

当用户调用stopService()unbindService()来停止服务时被系统调用,(整个生命周期只调用1次)用来释放onCreate()方法中创建的资源

void onDestroy()

通过startService()方法启动的服务

      初始化结束后系统会调用该方法,用于处理传递给startService()Intent对象。如音乐服务会打开Intent来探明将要播放哪首音乐,并开始播放。注意:多次调用startService()方法会多次触发onStart()方法

void onStart(Intent intent)

通过bindService ()方法启动的服务

      初始化结束后系统会调用该方法,用来绑定传递给bindServiceIntent的对象。注意:多次调用bindService()时,如果该服务已启动则不会再触发此方法

IBinder onBind(Intent intent)

用户调用unbindService()时系统调用此方法,Intent对象同样传递给该方法

boolean onUnbind(Intent intent)

如果有新的客户端连接至该服务,只有当旧的调用onUnbind()后,新的才会调用该方法

void onRebind(Intent intent)

补充onCreate(Bundle savedInstanceState)onSaveInstanceState(Bundle savedInstanceState)配合使用,见如下代码,达到显示activity被系统杀死前的状态

 

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        if (null != savedInstanceState) {

            String _userid = savedInstanceState.getString("StrUserId");

            String _uid = savedInstanceState.getString("StrUid");

            String _serverid = savedInstanceState.getString("StrServerId");

            String _servername = savedInstanceState.getString("StrServerName");

            int _rate = savedInstanceState.getInt("StrRate");

            //updateUserId(_userid);

            //updateUId(_uid);

            //updateServerId(_serverid);

            //updateUserServer(_servername);

            //updateRate(_rate);

        }

    }

 

    @Override

    protected void onSaveInstanceState(Bundle savedInstanceState) {

        super.onSaveInstanceState(savedInstanceState);

        savedInstanceState.putString("StrUserId", getUserId());

        savedInstanceState.putString("StrUid", getUId());

        savedInstanceState.putString("StrServerId", getServerId());

        savedInstanceState.putString("StrServerName", getServerName());

        savedInstanceState.putInt("StrRate", getRate());

    }

 

 

下面通过一个简单demo看看分别通过两种方式启动service时,这些回调函数的执行过程。

1startService()

1.新建一个StartLocalServiceActivity.java文件,定义两个按钮用来启动和停止service

package com.alexzhou.servicedemo;

 

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

 

//启动一个本地Service

public class StartLocalServiceActivity extends Activityimplements

        OnClickListener {

 

    private ButtonstartButton;

    private ButtonstopButton;

 

    private final StringLOCAL_START_SERVICE_ACTION ="com.alexzhou.service.LOCAL_START_SERVICE";

 

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.start_local_service);

        findViews();

        setListeners();

    }

 

    private void findViews() {

        startButton = (Button)this.findViewById(R.id.start);

        stopButton = (Button)this.findViewById(R.id.stop);

    }

 

    private void setListeners() {

        startButton.setOnClickListener(this);

        stopButton.setOnClickListener(this);

    }

 

    @Override

    public void onClick(View view) {

        switch (view.getId()) {

        case R.id.start:

            this.startService(new Intent(LOCAL_START_SERVICE_ACTION));

            break;

 

        case R.id.stop:

            this.stopService(new Intent(LOCAL_START_SERVICE_ACTION));

            break;

        }

 

    }

}

 

2.新建一个LocalService.java文件,这个就是本地service文件。

package com.alexzhou.servicedemo.service;

import android.app.Service;

import android.content.Intent;

import android.os.Binder;

import android.os.IBinder;

import android.util.Log;

//本地服务

public class LocalService extends Service {

 

    private final StringTAG = LocalService.class.getSimpleName();

 

    private LocalBindermBinder =new LocalBinder();

 

    public class LocalBinderextends Binder {

 

        public LocalService getService() {

            return LocalService.this;

        }

    }

 

    @Override

    public IBinder onBind(Intent intent) {

        Log.e(TAG,"onBind");

        return mBinder;

    }

 

    @Override

    public void onCreate() {

        Log.e(TAG,"onCreate");

        super.onCreate();

    }

 

    @Override

    public int onStartCommand(Intent intent, int flags,int startId) {

        Log.e(TAG,"onStartCommand");

        return super.onStartCommand(intent, flags, startId);

    }

 

    @Override

    public void onDestroy() {

        Log.e(TAG,"onDestroy");

        super.onDestroy();

    }

 

    public String getContent() {

        return "welcome access local service!";

    }

    

    } 

 

点击停止服务按钮,此时会执行:onDestory()方法销毁service


onCreate()方法在service第一次创建的时候会调用,如果该service已经运行了则不会执行该函数。

onStartCommand()方法是在其他组件通过调用startService()启动服务时才会执行。每次启动service时,onStartCommand()都会被执行。你多点几次启动服务按钮,会看到每次都会执行onStartCommand()

 

(2) bindService()

创建一个BindLocalServiceActivity.java文件,也同样弄两个button来绑定和解绑服务。

package com.alexzhou.servicedemo;

 

import android.app.Activity;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

 

import com.alexzhou.servicedemo.service.LocalService;

 

//绑定一个本地Service

public class BindLocalServiceActivity extends Activityimplements

        OnClickListener {

 

    private TextViewcallbackView;

    private ButtonbindButton;

    private ButtonunbindButton;

 

    private boolean isBind;

    private final StringLOCAL_BIIND_SERVICE_ACTION ="com.alexzhou.service.LOCAL_BIND_SERVICE";

    private LocalService mLocalService =null;

 

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.bind_local_service);

        findViews();

        setListeners();

        callbackView.setText("Not attached.");

    }

 

    private void findViews() {

        callbackView = (TextView)this.findViewById(R.id.callback);

        bindButton = (Button)this.findViewById(R.id.bind);

        unbindButton = (Button)this.findViewById(R.id.unbind);

    }

 

    private void setListeners() {

        bindButton.setOnClickListener(this);

        unbindButton.setOnClickListener(this);

    }

 

    @Override

    public void onClick(View view) {

        switch (view.getId()) {

        case R.id.bind:

            this.bindService(new Intent(LOCAL_BIIND_SERVICE_ACTION),

                    mConntectin, Context.BIND_AUTO_CREATE);

            isBind =true;

            callbackView.setText("binding...");

            break;

 

        case R.id.unbind: {

            if (isBind) {

 

                this.unbindService(mConntectin);

                isBind =false;

                callbackView.setText("unbind...");

            }

        }

            break;

 

        }

 

    }

 

    private ServiceConnectionmConntectin =new ServiceConnection() {

 

        @Override

        public void onServiceDisconnected(ComponentName arg0) {

            Log.i(BindLocalServiceActivity.class.getSimpleName(),

                    "onServiceDisConnected");

            callbackView.setText("Disconnected!");

            Toast.makeText(BindLocalServiceActivity.this,

                    R.string.remote_service_disconntected, Toast.LENGTH_SHORT)

                    .show();

        }

 

        @Override

        public void onServiceConnected(ComponentName name, IBinder binder) {

            Log.i(BindLocalServiceActivity.class.getSimpleName(),

                    "onServiceConnected");

            mLocalService =((LocalService.LocalBinder) binder).getService();

            callbackView.setText("attached!" +mLocalService.getContent());

 

            Toast.makeText(BindLocalServiceActivity.this,

                    R.string.remote_service_connected, Toast.LENGTH_SHORT)

                    .show();

        }

    };

 

    @Override

    protected void onDestroy() {

        super.onDestroy();

        if (isBind) {

            this.unbindService(mConntectin);

            isBind =false;

        }

 

    }

 

} 

点击绑定服务按钮,从Logcat输出的信息中可以看出调用顺序:onCreate()->onBind() ->onServiceConnnected()

同理onCreate()只会在service第一次创建时执行。

点击解绑服务,会调用serviceonDestory()方法。可以先调用startService(),然后再绑定该service,这样解除绑定的时候service就不会被销毁了,需要unbindService()stopService()都调用,服务才会销毁。注意:连接正常关闭的情况下,上述代码中onServiceDisconnected是不会调用的,只有在异常关闭的时候调用,比如被kill了。

 

 

 

 

0 0
原创粉丝点击