Android 四大组件之Service 的生命周期和使用

来源:互联网 发布:java match.group 编辑:程序博客网 时间:2024/05/17 22:16

Service简介:

Service 是Android的四大组件之一,一般用于没有UI界面,长期执行的后台任务,即使程序退出时,后台任务还在执行。比如:音乐播放。

Service的误区:

1.service在UI线程中执行。 2.不可以在service中执行耗时任务,因为service是在UI线程中运行的。 3.如果需要执行后台的耗时任务,必须在Service中开启一个线程来执行。

Service的生命周期:





启动和停止Service的两种方式 1.context.startService();context.stopService(). 2.context.bindService();context.unbindService().




Service使用实例1:

客户端代码如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.xjp.broadcast;
 
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
 
public class MainActivity extendsActivity {
 
    privatefinalstatic String action ="com.xjp.MainActivity";
 
    privateTextView result;
 
    privateButton startService;
    privateButton stopService;
 
 
 
    privateBroadcastReceiver broadcastReceiver =newBroadcastReceiver() {
        @Override
        publicvoidonReceive(Context context, Intent intent) {
 
            inti = intent.getIntExtra("key",0);
 
            result.setText(i +"");
        }
    };
 
 
    @Override
    protectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        result = (TextView) findViewById(R.id.result);
 
        startService = (Button) findViewById(R.id.startService);
        startService.setOnClickListener(newView.OnClickListener() {
            @Override
            publicvoidonClick(View v) {
                Intent service =newIntent(MainActivity.this, CalculationService.class);
                startService(service);
            }
        });
 
        stopService = (Button) findViewById(R.id.stopService);
        stopService.setOnClickListener(newView.OnClickListener() {
            @Override
            publicvoidonClick(View v) {
                Intent service =newIntent(MainActivity.this, CalculationService.class);
                stopService(service);
            }
        });
    }
 
 
    @Override
    protectedvoidonResume() {
        super.onResume();
        initFilter();
    }
 
    @Override
    protectedvoidonDestroy() {
        super.onDestroy();
        unregisterReceiver(broadcastReceiver);
    }
 
    privatevoidinitFilter() {
        IntentFilter filter =newIntentFilter();
        filter.addAction(action);
        registerReceiver(broadcastReceiver, filter);
    }
 
 
}

1.依次点击“启动服务” 和“停止服务” ,生命周期 打印结果如下:


2.点击两次 “启动服务” 打印结果如下:


这种方式可以多次启动同一个Service,并且 只有第一次才执行 onCreate。第二次之后 就只执行 onStartCommand,并且当且仅当该应用退出之后,该服务依然存在后台运行着。退出之后,在设置里面查看正在运行的应用:





服务端代码如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.xjp.broadcast;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
 
/**
 * Description:
 * User: xjp
 * Date: 2015/5/4
 * Time: 14:14
 */
 
public class CalculationService extendsService {
 
    privatefinalstatic String TAG = "CalculationService";
    privatefinalstatic String action ="com.xjp.MainActivity";
 
    privatebooleanquit = false;
 
 
 
    @Override
    publicIBinder onBind(Intent intent) {
        Log.e(TAG,"====onBind=====");
        returnnull;
    }
 
 
    @Override
    publicbooleanonUnbind(Intent intent) {
        Log.e(TAG,"====onUnbind=====");
        returnsuper.onUnbind(intent);
    }
 
    @Override
    publicvoidonCreate() {
        Log.e(TAG,"====onCreate=====");
        super.onCreate();
    }
 
 
    @Override
    publicintonStartCommand(Intent intent,intflags, int startId) {
        Log.e(TAG,"====onStartCommand=====");
        startThread();
        returnsuper.onStartCommand(intent, flags, startId);
 
 
    }
 
    @Override
    publicvoidonDestroy() {
        Log.e(TAG,"====onDestroy=====");
        quit =true;
        super.onDestroy();
    }
 
 
    /**
     * 开启线程模拟耗时任务
     */
    publicvoidstartThread() {
        newThread(newRunnable() {
            inti =0;
 
            @Override
            publicvoidrun() {
                while(i <200 && !quit) {
                    try{
                        Thread.sleep(1000);
                        i++;
                        Intent intent =newIntent(action);
                        intent.putExtra("key", i);
                        sendBroadcast(intent);
                    }catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
 
}



Service使用实例2:

客户端代码如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.xjp.broadcast;
 
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
 
public class MainActivity extendsActivity {
 
    privatefinalstatic String action ="com.xjp.MainActivity";
 
    privateTextView result;
 
    privateButton startService;
    privateButton stopService;
 
    privateCalculationService calculationService;
 
 
    privateBroadcastReceiver broadcastReceiver =newBroadcastReceiver() {
        @Override
        publicvoidonReceive(Context context, Intent intent) {
 
            inti = intent.getIntExtra("key",0);
 
            result.setText(i +"");
        }
    };
 
    privateServiceConnection serviceConnection =newServiceConnection() {
        @Override
        publicvoidonServiceConnected(ComponentName name, IBinder service) {
            calculationService = ((CalculationService.CalulationBinder) service).getService();
            calculationService.startThread();
        }
 
        @Override
        publicvoidonServiceDisconnected(ComponentName name) {
            calculationService =null;
        }
    };
 
    @Override
    protectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        result = (TextView) findViewById(R.id.result);
 
        startService = (Button) findViewById(R.id.startService);
        startService.setOnClickListener(newView.OnClickListener() {
            @Override
            publicvoidonClick(View v) {
                Intent service =newIntent(MainActivity.this, CalculationService.class);
                bindService(service, serviceConnection, Context.BIND_AUTO_CREATE);
            }
        });
 
        stopService = (Button) findViewById(R.id.stopService);
        stopService.setOnClickListener(newView.OnClickListener() {
            @Override
            publicvoidonClick(View v) {
                unbindService(serviceConnection);
            }
        });
    }
 
 
    @Override
    protectedvoidonResume() {
        super.onResume();
        initFilter();
    }
 
    @Override
    protectedvoidonDestroy() {
        super.onDestroy();
        unregisterReceiver(broadcastReceiver);
    }
 
    privatevoidinitFilter() {
        IntentFilter filter =newIntentFilter();
        filter.addAction(action);
        registerReceiver(broadcastReceiver, filter);
    }
 
 
}

服务端代码如下:
?
1
 
?
1
 
package com.xjp.broadcast; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; /** * Description: * User: xjp * Date: 2015/5/4 * Time: 14:14 */ public class CalculationService extends Service { private final static String TAG = "CalculationService"; private final static String action = "com.xjp.MainActivity"; private boolean quit = false; private IBinder binder = new CalulationBinder(); public class CalulationBinder extends Binder { public CalculationService getService() { return CalculationService.this; } } @Override public IBinder onBind(Intent intent) { Log.e(TAG, "====onBind====="); return binder; } @Override public boolean onUnbind(Intent intent) { Log.e(TAG, "====onUnbind====="); return super.onUnbind(intent); } @Override public void onCreate() { Log.e(TAG, "====onCreate====="); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "====onStartCommand====="); startThread(); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.e(TAG, "====onDestroy====="); quit = true; super.onDestroy(); } /** * 开启线程模拟耗时任务 */ public void startThread() { new Thread(new Runnable() { int i = 0; @Override public void run() { while (i < 200 && !quit) { try { Thread.sleep(1000); i++; Intent intent = new Intent(action); intent.putExtra("key", i); sendBroadcast(intent); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } } 


?
1
 
?
1
 
一次点击“启动服务”按钮和 “停止服务” 按钮,生命周期 打印结果如下:
?
1
 


绑定服务,如果退出的时候没有解除绑定 ,也就是没有调用 context.unbindService().的话,会报错误。所以,一般都在客户端的 onDestory()中调用 context.unbindService(). 所以这种服务不太适合后台长时间的任务。 这种服务绑定和解除绑定是成对出现的。

两种Service总结:


第一种,非绑定的Service,应用退出时可以不停止服务退出。可以让服务一直在后台运行。缺点:启动服务即 启动后台任务,不能很好的在客户端随时控制 服务的后台任务执行时间。 第二种,绑定的Service,应用退出时必须解除绑定Service,否则程序报错。优点:不过绑定的Service可获得 Service 的Binder,可以灵活控制 Service里的各种方法的调用。
0 0
原创粉丝点击