Android-Service生命周期

Service的基本概念,以及Service的生命周期:

一、Service的基本概念:

一个Service就是应用程序的组件,可以在后台长期跑,或者是为其他的应用提供功能上的支持。Service一般与Activity相对理解,它是没有Activity的界面的,Service也具有自己的独特生命周期,一个Service需要在AndroidManifest.xml中进行配置,

<application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="com.li.xiami.ServiceActivity1"

            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=".StartActivity"></service>

    </application>

注意:这个里面也可以增加android:process=".remote"来设置是远程调用,然后就是remote service

可以通过Context.startService()或者是Context.bindService()来启动Service;service是跑在宿主进程的主线程中,那么如果你的service需要做消耗CPU或者是阻塞的操作,那么应该重新开一个线程来处理这些耗时的操作。IntentService是继承自Service的,它会帮你重开一个线程来执行耗时操作。

注:Service既不是一个独立的进程,也不是一个线程,其实Service就是两个特性,也是跟生命周期结合起来的,一个是能够在后台一直跑,可以通过startService启动,一个是能够与其他应用进行交互,通过bindService建立连接,进行通信

Service具体的实现有两种,一个是localService,一个是通过AIDL来实现remoteService。

二、Service的生命周期:

先来一张经典的生命周期图示:

 

所涉及到的所有跟Service相关的函数包括:

 onCreate()——Create只执行一次

onStartCommand()——可以多次执行

onDestory()——只执行一次

onBind()——绑定也只执行一次

onUnBind()——解绑也只执行一次

startService的生命周期:

onCreate()-onStartCommand()-onDestory():startService的时候会调onCreate(),但是只调一次,onStartCommand()可以被调用多次

StartService的程序实现:

 1 package com.li.xiami;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.IBinder;
 6 import android.util.Log;
 7 
 8 public class startService extends Service {
 9 
10     private final String tag = "service";
11     
12     @Override
13     public IBinder onBind(Intent intent) {
14         // TODO Auto-generated method stub
15         return null;
16     }
17 
18     @Override
19     public void onCreate() {
20         // TODO Auto-generated method stub
21         Log.v(tag, "onCreate()");
22         super.onCreate();
23     }
24 
25     @Override
26     public void onDestroy() {
27         // TODO Auto-generated method stub
28         Log.v(tag, "onDestory()");
29         super.onDestroy();
30     }
31 
32     @Override
33     public int onStartCommand(Intent intent, int flags, int startId) {
34         // TODO Auto-generated method stub
35         Log.v(tag, "onStartCommand()");
36         return super.onStartCommand(intent, flags, startId);
37     }    
38 
39 }
 1 package com.li.xiami;
 2 
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.content.Intent;
 6 import android.util.Log;
 7 import android.view.Menu;
 8 import android.view.View;
 9 import android.widget.Button;
10 import android.widget.Toast;
11 
12 public class MainActivity extends Activity {
13 
14     private Button buttonstart;
15     private Button buttonstop;
16     private Button buttonsecondstart;
17     
18     private final String tag = "Activity";
19     
20     Intent intent = new Intent();
21     
22     @Override
23     protected void onCreate(Bundle savedInstanceState) {
24         super.onCreate(savedInstanceState);
25         setContentView(R.layout.activity_main);
26         
27         buttonstart = (Button) findViewById(R.id.buttonstartservice);
28         buttonstop = (Button) findViewById(R.id.buttonstopservice);
29         buttonsecondstart = (Button) findViewById(R.id.buttonsencondstart);
30         
31         intent.setClass(MainActivity.this, startService.class);
32         
33         buttonstart.setOnClickListener(onClick);
34         buttonstop.setOnClickListener(onClick);
35         buttonsecondstart.setOnClickListener(onClick);
36         
37     }
38     
39     //这个匿名内部类的统一实现,要放在onCreate()的外面,这样这个先被初始化,然后onCreate()里面的button就能够找到这个对象
40     View.OnClickListener onClick = new View.OnClickListener() {
41         
42         @Override
43         public void onClick(View v) {
44             //switch里面写v.getId()。。。
45             switch(v.getId()){
46             case R.id.buttonstartservice:
47                 //Toast.makeText().show()——之前只makeText了,也没有show()啊,笨蛋!!!
48                 Toast.makeText(MainActivity.this, "startService", Toast.LENGTH_SHORT).show();
49                 startService(intent);
50                 Log.v(tag, "start service");
51                 break;
52             case R.id.buttonstopservice:
53                 Toast.makeText(MainActivity.this, "stopService", Toast.LENGTH_SHORT).show();
54                 stopService(intent);
55                 Log.v(tag, "stop service");
56                 break;
57                 
58             case R.id.buttonsencondstart:
59                 Toast.makeText(getApplicationContext(), "secondStartService", Toast.LENGTH_SHORT).show();
60                 startService(intent);
61                 Log.v(tag, "second start service");
62                 break;
63             
64             }    
65         }
66     };
67     
68 
69     @Override
70     public boolean onCreateOptionsMenu(Menu menu) {
71         // Inflate the menu; this adds items to the action bar if it is present.
72         getMenuInflater().inflate(R.menu.main, menu);
73         return true;
74     }
75 
76 }

AndroidManifest.xml中注册Service:

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

之后执行结果:

 从startService的生命周期的运行log中就可以看到,Activity中执行startService()之后,Service执行回调函数onCreate()-onStartCommand(),之后再进行一次startService的话,只会执行onStartCommand(),Activity中执行stopService()的话,Service直接执行onDestory()。

Unbounded service:

bindService()的生命周期:

onCreate()-onBind()-onUnBind()-onDestory(),所有都是只执行一次,onBind()函数也是只执行一次

bindService的程序实现:(通过IBinder接口来实现,在Service中实现一个继承自Binder的类,然后在onBind()中返回一个Binder的对象,在Activity中通过得到这个Binder对象来进行通信)

 1 package com.li.xiami;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.Binder;
 6 import android.os.IBinder;
 7 import android.util.Log;
 8 
 9 public class BindService extends Service {
10     
11     public final String tag = "service";
12     
13     public class MyBinder extends Binder{
14         String state = "绑定绑定获取binder的数据";
15         String getState(){
16             return state;
17         }
18     }
19     
20     MyBinder mybinder = new MyBinder();
21     
22     @Override
23     public IBinder onBind(Intent intent) {
24         // TODO Auto-generated method stub
25         Log.v(tag, "onBind()");
26         return mybinder;
27     }
28 
29     @Override
30     public void onCreate() {
31         // TODO Auto-generated method stub
32         Log.v(tag, "onCreate()");
33         super.onCreate();
34     }
35 
36     @Override
37     public void onDestroy() {
38         // TODO Auto-generated method stub
39         Log.v(tag, "onDestory()");
40         super.onDestroy();
41     }
42 
43     @Override
44     @Deprecated
45     public void onStart(Intent intent, int startId) {
46         // TODO Auto-generated method stub
47         Log.v(tag, "onStart()");
48         super.onStart(intent, startId);
49     }
50 
51     @Override
52     public int onStartCommand(Intent intent, int flags, int startId) {
53         // TODO Auto-generated method stub
54         Log.v(tag, "onStartCommand()");
55         return super.onStartCommand(intent, flags, startId);
56     }
57 
58     @Override
59     public boolean onUnbind(Intent intent) {
60         // TODO Auto-generated method stub
61         Log.v(tag, "onUnBind()");
62         return super.onUnbind(intent);
63     }
64     
65 }
package com.li.xiami;

import com.li.xiami.BindService.MyBinder;

import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

    
    private Button buttonbind;
    private Button buttongetstate;
    private Button buttonunbind;
    
    Intent intent = new Intent();
    BindService.MyBinder mybinder = null;
    
    private final String tag = "Activity";
    
    boolean isBound = false;
    
    ServiceConnection conn = new ServiceConnection(){

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            mybinder = (MyBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
            mybinder = null;
        }
        
    };
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        
        buttonbind = (Button) findViewById(R.id.buttonbind);
        buttongetstate = (Button) findViewById(R.id.buttongetstate);
        buttonunbind = (Button) findViewById(R.id.buttonunbind);
        
        intent.setClass(MainActivity.this, BindService.class);
        
        buttonbind.setOnClickListener(onClick);
        buttongetstate.setOnClickListener(onClick);
        buttonunbind.setOnClickListener(onClick);
        
    }
    
    
    View.OnClickListener onClick = new View.OnClickListener() {
        
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            switch(v.getId()){
            case R.id.buttonbind:
                Log.v(tag, "bindservice");
                bindService(intent, conn, Service.BIND_AUTO_CREATE);
                Toast.makeText(getApplicationContext(), "绑定服务", Toast.LENGTH_SHORT).show();
                isBound = true;
                break;
            case R.id.buttongetstate:
                Log.v(tag, "getstate");
                if(isBound == true){
                    Toast.makeText(getApplicationContext(), "获取服务状态:"+mybinder.getState(), Toast.LENGTH_SHORT).show();
                }
                else{
                    Toast.makeText(getApplicationContext(), "还没绑定,请绑定", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.buttonunbind:
                if(isBound == true){
                    Log.v(tag, "unbind");
                    Toast.makeText(getApplicationContext(), "解除绑定", Toast.LENGTH_SHORT).show();
                    unbindService(conn);
                    isBound = false;
                }
                else{
                    Toast.makeText(getApplicationContext(), "还没绑定,请绑定", Toast.LENGTH_SHORT).show();
                }
                break;
            }
        }
    };
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

AndroidManifest.xml中注册Service:

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

之后执行结果:

 从log中也可以看出,在Activity中多次执行bindService()也没有重复执行onBind()

原文地址:https://www.cnblogs.com/keke-xiaoxiami/p/4351252.html