感覺Service有些糾結,不知道是不是因為書本的原因,書上的例子一個都沒成功,看的也是暈頭轉向的。
一同提到了4個東西,前面嘛自然是那些巴拉巴拉的介紹,直接正題。
重點:
1.創建一個服務(Service);
Android中Service是一個很重要的元素之一,一個 “服務”涉及到Service類的繼承,以及在AndroidManifest.xml中添加相關權限許可代碼
再者就是 Service類的基礎方法,onCreate(), onBind(), onStart(), onStartCommand(), onDestory()......
定義服務的名稱很重要,因為這可以讓你的服務在其他應用程序中被使用(創建,啟動,停止,銷毀).對於onStart() 和 onCommand() 方法在功能上是一致的,
只是前者( onStart() )在API L5以上就已經廢除了, 取而代之的就是onStartCommand(), 一般後者( onStartCommand() )的默認實現是調用onStart(),並且返回某個值以便於與舊版本兼容。
聲明周期:i> Context.StartService() 啟動一個服務, onCreate() -> onStart() 或者 onCommand() -> Context.stopService() 或者 stopSelf() -> onDestory() .
ii> Context.bindService() 綁定一個服務, onCreate() -> onBind() -> Context.unbindService() 或者 onUnBind() -> stioSelf() -> onDestory().
看起來又長有復雜,當你自己去用的時候會清晰很多。
實例:
復制代碼
1 package com.qimu.service;
2
3 import android.app.Service;
4 import android.content.BroadcastReceiver;
5 import android.content.Context;
6 import android.content.Intent;
7 import android.content.IntentFilter;
8 import android.os.IBinder;
9 import android.os.SystemClock;
10 import android.util.Log;
11
12 public class QiMuService extends Service {
13
14 qimuReceiver recevier;
15
16 @Override
17 public IBinder onBind(Intent intent) {
18
19 return null;
20 }
21
22 private static final String DEBUG_TAG = "QiMu_DEBUG";
23
24 public void onCreate() {
25
26 Log.v( DEBUG_TAG, "Service starting" );
27
28 recevier = new qimuReceiver();
29
30 super.onCreate();
31 }
32
33 public void onStart( Intent intent, int startId ) {
34
35 System.out.println( "Start sucess" );
36
37 IntentFilter filter = new IntentFilter();
38 filter.addAction("com.qimu.QiMuService");
39 registerReceiver( recevier, filter );
40
41 for ( int i = intent.getIntExtra( "_start", 0 ); i < 100; i++ ) {
42
43 SystemClock.sleep( 200 );
44 if ( i % 5 == 0) {
45 System.out.println( i );
46 Intent activityCallBack = new Intent();
47 activityCallBack.setAction( "com.qimu.MainActivity" );
48 activityCallBack.putExtra( "_time", i );
49 sendBroadcast( activityCallBack );
50 }
51 }
52
53 onDestory();
54 }
55
56 public int onStartCommand( Intent intent, int flags, int startId ) {
57
58 onStart(intent, startId);
59 return Service.START_REDELIVER_INTENT;
60 }
61
62 public void onDestory() {
63
64 super.onDestroy();
65 }
66
67 public class qimuReceiver extends BroadcastReceiver {
68
69 @Override
70 public void onReceive(Context context, Intent intent) {
71 //......
72 }
73
74 }
75
76 }
復制代碼
復制代碼
1 package com.qimu.service;
2
3 import android.annotation.SuppressLint;
4 import android.app.Activity;
5 import android.content.BroadcastReceiver;
6 import android.content.Context;
7 import android.content.Intent;
8 import android.content.IntentFilter;
9 import android.os.Bundle;
10 import android.view.View;
11 import android.widget.TextView;
12
13 public class MainActivity extends Activity {
14
15 TextView tv_service;
16 qimuBroadcast broadcast;
17
18 @Override
19 protected void onCreate(Bundle savedInstanceState) {
20 super.onCreate(savedInstanceState);
21 setContentView(R.layout.activity_main);
22
23 tv_service = ( TextView ) findViewById( R.id.service );
24
25 tv_service.setOnClickListener(new View.OnClickListener() {
26
27 @Override
28 public void onClick(View arg0) {
29 // TODO Auto-generated method stub
30 //Intent serviceIntent = new Intent( MainActivity.this, com.qimu.service.QiMuService.class );
31 //serviceIntent.putExtra( "_start", 1 );
32 //startService( serviceIntent );
33 Intent intent = new Intent("com.qimu.service.QiMuService");
34 intent.putExtra("_start", 1 );
35 startService(intent);
36 }
37 });
38 }
39
40 public void onStart() {
41
42 System.out.println("Start sucess......");
43 broadcast = new qimuBroadcast();
44 IntentFilter intentfilter = new IntentFilter();
45 intentfilter.addAction("com.qimu.MainActivity");
46 registerReceiver( broadcast, intentfilter );
47 super.onStart();
48 }
49
50 public void onStop() {
51
52 unregisterReceiver( broadcast );
53 super.onStop();
54 }
55
56 public class qimuBroadcast extends BroadcastReceiver {
57
58 @SuppressLint("ShowToast")
59 @Override
60 public void onReceive( Context context, Intent intent ) {
61
62 int _time = intent.getIntExtra( "_time", -1 );
63 tv_service.setText( "" + _time );
64 }
65 }
66
67 }
復制代碼
書上的例子沒成功,所以自己寫了一個簡單的Service和Activity之間通信的例子,感覺有點挫,不過大體功能是實現了,從Service的注冊,創建,啟動,調用BroadcastReceiver傳遞數據,停止,銷毀都用了一遍,還是蠻簡單的。
2.實現遠程結構(AIDL);
當然你費很大功夫寫了一個程序,肯定會考慮到跟其他應用程序的“交流”問題(執行其他調用),所以很明顯的就會涉及到接口(遠程接口)問題,AIDL就是解決這個問題的核心所在了。你要定義遠程接口,首先你必須創建一個AIDL文件,在文件中聲明接口,然後實現這個接口,並且在onBind()方法被調用時返回這個接口(感覺不太清楚,看代碼應該是,創建了一個類來實現這個接口,返回這個類的實例)的實例。
咳咳,自己第一次做的時候連eclipse怎麼創建一個AIDL文件都不知道,不過總是有好心人在某個角落留下了例子(鏈接:http://my.oschina.net/u/779520/blog/79936)。
接著我們就可以通過其接口來實用服務了,這時候就涉及到ServiceConnection的兩個方法,onServiceConnected()和onServiceDisconnected()來實現Service的連接和釋放連接(注:遠程接口調用將進行跨線程的操作,並且同步完成,如果調用需要消耗比較長的時間,那麼應該向其他的耗時調用一樣在另外的線程中進行處理)。
注:在另外的程序中需要使用這個接口的時候,需要在工程中添加AIDL文件以及相應的包(說的普通點就是涉及到的程序中都要有這個接口文件,一個(主人家)是實現,剩下的(客人)用來調用它)。
實例:
服務端AIDL文件
服務端Service實現
客服端調用
很簡單的一個例子,在客服端程序中有2個Button,1個TextView,點擊bt_1綁定並啟用服務,點擊bt_2獲取服務端實現的功能(返回一個字符串)。
3.實現可包裝類(Parcelable)
Parcelable類主要是用來封裝數據,便於傳輸,關於它的實用附上鏈接:http://blog.sina.com.cn/s/blog_78e3ae430100pxba.html,沒什麼太多好看的,書上提到了也就看了一下。
4.IntentService類
在程序設計中,你會需要處理很多高頻率的請求,將這些需要周期性執行的任務放在一個工作隊列中,會使得你的程序簡單而高效,同時還可以避免創建一個完整的麻煩的Service,IntentService是一個簡單的服務,它可以用Intent請求的方法來處理異步的任務,每個Intent都會被添加到與IntentService相關的工作隊列中,然後序列化的進行處理,對於返回結果,你可以選擇通過廣播( sendBroadcast()方法 )向應用程序發送Intent對象,並使用應用程序中的廣播接收器(BroadcastReceiver)來捕獲這些結果。
實例:1中有使用......嘿嘿......
總結:Android SDK所提供的Service機制真的很強大,一個優秀的Service可以顯著的增強應用程序或所提供服務的吸引力, 但是在創建實現一個後台服務的時候要很注意才行,粗糙的設計可能會對實用的移動端的性能和電池的續航能力造成本質上的影響(所以綜合測試的時候要特別注意對Service的考慮)。