Android金毛狮王之Service

来源:互联网 发布:网络分线器很慢 编辑:程序博客网 时间:2024/04/29 16:11

传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229

        本节我们学习Android四大天王的Service,如果把Activity比作是前台程序,那么Service就是后台程序,Service的整个生命周期只会在后台执行。它一般没有用户操作界面,运行于系统中不容易被用户发觉,可以用来开发如监控之类的程序。与Activity一样,Service也是通过Intent来调用。

一、创建Service
1.继承API的Service类
public class CustomService extends Service {...}

2.在AndroidManifest.xml的<application>标签中对创建的Service进行注册

<service android:name=".MyService" />

二、启动Service

        服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法使用场合有所不同。
1.采用Context.startService()方法启动服务
        当服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStartCommand(...)方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStartCommand(...)方法。采用startService()方法启动的服务,只能调用stopService()方法结束服务,服务结束时会调用onDestroy()方法。采用这种方式启用服务,调用者与服务之间没有关联,即使调用者退出了,服务仍然运行。 
2.采用Context.bindService()方法启动服务
        当服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()方法,接着调用onDestroy()方法。采用这种方式启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。

三、Service生命周期

        既然官方没有为Service生命周期提供示意图,那么我们就模仿Activity生命周期示意图绘制一张,然后再进行总结。


        从上图可以看出,其实Service的生命周期可以分为如下两个场景:
1.由Context.startService()启动生命周期:startService() ☞ onCreate() ☞ onStartCommand() ☞ stopService() ☞ onDestroy()
        多次调用startService()方法尽管不会多次创建服务,但onStartCommand()方法会被多次调用。
2.由Context.bindService()启动生命周期:bindService() ☞ onCreate() ☞ onBind() ☞ unbindService() ☞ onUnbind() ☞ onDestroy()
        当调用者与服务已经绑定时,多次调用bindService()方法并不会导致onBind()方法被多次调用。
四、Service案例

1.案例代码陈列

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="cn.lynn.service"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="15" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <service android:name=".MyService" />    </application></manifest>

strings.xml

<resources>    <string name="app_name">Android四大天王之Service</string></resources>
main.xml
<?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/btnStartMyService"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="StartMyService" />    <Button        android:id="@+id/btnStopMyService"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="StopMyService" />    <Button        android:id="@+id/btnBindMyService"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="BindMyService" />    <Button        android:id="@+id/btnUnbindMyService"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="UnbindMyService" />    <Button        android:id="@+id/btnExitActivity"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="ExitActivity" /></LinearLayout>

MainActivity.java

package cn.lynn.service;import cn.lynn.service.R;import android.app.Activity;import android.app.Service;import android.content.ComponentName;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.widget.Button;public class MainActivity extends Activity {    private static final String TAG = "MainActivity";    Button mBtnStartMyService;    Button mBtnStopMyService;    Button mBtnBindMyService;    Button mBtnUnbindMyService;    Button mBtnExitActivity;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        mBtnStartMyService = (Button) findViewById(R.id.btnStartMyService);        mBtnStartMyService.setOnClickListener(new MyOnClickListener());        mBtnStopMyService = (Button) findViewById(R.id.btnStopMyService);        mBtnStopMyService.setOnClickListener(new MyOnClickListener());        mBtnBindMyService = (Button) findViewById(R.id.btnBindMyService);        mBtnBindMyService.setOnClickListener(new MyOnClickListener());        mBtnUnbindMyService = (Button) findViewById(R.id.btnUnbindMyService);        mBtnUnbindMyService.setOnClickListener(new MyOnClickListener());        mBtnExitActivity = (Button) findViewById(R.id.btnExitActivity);        mBtnExitActivity.setOnClickListener(new MyOnClickListener());    }    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {        }        @Override        public void onServiceConnected(ComponentName name, IBinder service) {        }    };    class MyOnClickListener implements View.OnClickListener {        @Override        public void onClick(View v) {            Intent intent = new Intent(MainActivity.this, MyService.class);            switch (v.getId()) {            case R.id.btnStartMyService:                MainActivity.this.startService(intent);                break;            case R.id.btnStopMyService:                MainActivity.this.stopService(intent);                break;            case R.id.btnBindMyService:                MainActivity.this.bindService(intent, conn, Service.BIND_AUTO_CREATE);                break;            case R.id.btnUnbindMyService:                if (MyService.ServiceState.equals("onBind")) {                    MainActivity.this.unbindService(conn);                }                break;            case R.id.btnExitActivity:                MainActivity.this.finish();                break;            default:                break;            }        }    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.i(TAG, "onDestory");    }}

MyService.java

package cn.lynn.service;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class MyService extends Service {    private static final String TAG = "MyService";    // 记录Service生命周期的各个状态    public static String ServiceState = "";    @Override    public IBinder onBind(Intent intent) {        Log.i(TAG, "onBind");        ServiceState = "onBind";        return null;    }    @Override    public boolean onUnbind(Intent intent) {        super.onUnbind(intent);        Log.i(TAG, "onUnbind");        ServiceState = "onUnbind";        return false;    }    @Override    public void onCreate() {        super.onCreate();        Log.i(TAG, "onCreate");        ServiceState = "onCreate";    }        @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.i(TAG, "onStartCommand");        ServiceState = "onStartCommand";        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        super.onDestroy();        Log.i(TAG, "onDestroy");        ServiceState = "onDestroy";    }}

2.案例效果展示


        点击“StartMyService”按钮,执行startService(...)方法,控制台LogCat输出如下:


        点击“StopMyService”按钮,执行stopService(...)方法,控制台LogCat输出如下:


        点击“BindMyService”按钮,执行bindService(...)方法,控制台LogCat输出如下:


        点击“UnBindMyService”按钮,执行unbindService(...)方法,控制台LogCat输出如下:


3.案例源码下载

点我下载源码