Android中的Serializable、Parcelable">Android中的Serializable、Parcelable
786
2022-05-30
作用:
是在后臺長期運行某些服務(wù),如復(fù)雜的計算 、音樂播放、下載等等。
分類:
Service按運行的位置劃分有:本地服務(wù)、遠程服務(wù)
Service按運行的類型劃分有:前臺服務(wù)、后臺服務(wù)
Service按運行的功能劃分有:可通信服務(wù)、不可通信服務(wù)
下面逐一講解。
本地服務(wù)與遠程服務(wù)
本地服務(wù)使用步驟
本地服務(wù)使用步驟1: 新建子類繼承Service類,重寫父類的onCreate()、onStartCommand()、onDestroy()和onBind()方法。
package com.ti.myservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; // 本地Service這是最常用的 public class LocalService extends Service { public LocalService() { } @Override public void onCreate() { super.onCreate(); Log.d("本地Service#","onCreate創(chuàng)建服務(wù)"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("本地Service#","onStartCommand開始服務(wù)"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d("本地Service#","onDestroy銷毀服務(wù)"); } @Override public IBinder onBind(Intent intent) { Log.d("本地Service#","onBind綁定服務(wù)"); return null; } }
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
本地服務(wù)使用步驟2: 在AndroidManifest.xml里注冊Service
1
2
3
4
5
6
7
8
9
10
11
12
AndroidManifest.xml里Service標簽的常見屬性:
本地服務(wù)使用步驟3: 構(gòu)建用于啟動Service的Intent對象
啟動Service Intent
Intent startLocalServiceIntent = new Intent(MainActivity.this,LocalService.class);
1
終止Service Intent
Intent stopLocalServiceIntent = new Intent(MainActivity.this,LocalService.class);
1
本地服務(wù)使用步驟4:
調(diào)用startService()啟動Service
Intent startLocalServiceIntent = new Intent(MainActivity.this,LocalService.class); startService(startLocalServiceIntent);
1
2
調(diào)用stopService()停止服務(wù)
Intent stopLocalServiceIntent = new Intent(MainActivity.this,LocalService.class); stopService(stopLocalServiceIntent);
1
2
本地服務(wù)運行結(jié)果:
2019-07-22 18:27:59.377 17266-17266/com.ti.myservice D/本地Service#: onCreate創(chuàng)建服務(wù) 2019-07-22 18:27:59.378 17266-17266/com.ti.myservice D/本地Service#: onStartCommand開始服務(wù) 2019-07-22 18:28:09.813 17266-17266/com.ti.myservice D/本地Service#: onDestroy銷毀服務(wù)
1
2
3
遠程服務(wù)使用
遠程服務(wù)(Remote Service)也被稱之為獨立進程,它不受其它進程影響,可以為其它應(yīng)用程序提供調(diào)用的接口——實際上就是進程間通信IPC(Inter-Process Communication),Android提供了AIDL(Android Interface Definition Language,接口描述語言)工具來幫助進程間接口的建立。
在Android中,不同的應(yīng)用屬于不同的進程(Process),一個進程不能訪問其它進程的存儲,但是可以通過ContentProvider實現(xiàn),如:通訊錄的讀取。
遠程服務(wù)與本地服務(wù)最大的區(qū)別是:遠程Service與調(diào)用者不在同一個進程里(即遠程Service是運行在另外一個進程);而本地服務(wù)則是與調(diào)用者運行在同一個進程里。
將一個Service變成遠程服務(wù),加上android:process=":remote"就可以了,然后它就在另一個進程里自己運行了,你要和它通信就要用AIDL的方式了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
遠程服務(wù)的講解,獨立成一章《遠程服務(wù)Service & AIDL & IPC》
前臺服務(wù)與后臺服務(wù)
前臺服務(wù)使用步驟
創(chuàng)建前臺服務(wù)步驟1:
編寫繼承Service的子類,重寫onCreate()方法,在其中開啟前臺線程。這樣既可以使用startService(),也可以使用bindService()開啟前臺服務(wù),因為它們都會執(zhí)行onCreate方法。
如果把開啟前臺線程寫到onStartCommand(),那么只能用startService()開啟前臺服務(wù),bindService()就開啟不了,因為用bindService開啟,onStartCommand不會被執(zhí)行。
如果把開啟前臺線程寫到onBind,那么只能用用bindService開啟,因為startService調(diào)用時,onBind不會被執(zhí)行。而只有onCreate是兩種開啟方法時都會被調(diào)用的。
@Override public void onCreate() { super.onCreate(); String id = "channel_01"; String name="我是渠道名字"; // 添加下列代碼將后臺Service變成前臺Service // 構(gòu)建點擊通知后打開MainActivity的Intent對象 Intent notificationIntent = new Intent(this,MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT); //獲取系統(tǒng)通知服務(wù) NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW); notificationManager.createNotificationChannel(mChannel); notification = new Notification.Builder(this,id) .setContentTitle("前臺服務(wù)通知的標題")// 設(shè)置通知的標題 .setContentText("前臺服務(wù)通知的內(nèi)容")// 設(shè)置通知的內(nèi)容 .setSmallIcon(R.mipmap.ic_launcher)// 設(shè)置通知的圖標 .setContentIntent(pendingIntent)// 設(shè)置點擊通知后的操作 .build(); } else { notification = new NotificationCompat.Builder(this) .setContentTitle("前臺服務(wù)通知的標題") .setContentText("前臺服務(wù)通知的內(nèi)容") .setSmallIcon(R.mipmap.ic_launcher) .setOngoing(true) .setChannelId(id) .setContentIntent(pendingIntent) //設(shè)置pendingIntent,點擊通知時就會用到 .build(); } startForeground(1, notification);// 讓Service變成前臺Service,并在系統(tǒng)的狀態(tài)欄顯示出來 Log.d("前臺Service#","onCreate創(chuàng)建服務(wù)"); }
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
創(chuàng)建前臺服務(wù)步驟2:
在AndroidManifest.xml中注冊服務(wù)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
創(chuàng)建前臺服務(wù)步驟3:開啟服務(wù)。
用startService開啟
Intent startFrontServiceIntent = new Intent(MainActivity.this,FrontService.class); startService(startFrontServiceIntent);
1
2
關(guān)閉
Intent stopFrontServiceIntent = new Intent(MainActivity.this,FrontService.class); stopService(stopFrontServiceIntent);
1
2
用bindService綁定服務(wù):
private ServiceConnection testServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { } @Override public void onServiceDisconnected(ComponentName name) { } }; bindService(startFrontServiceIntent,testServiceConnection,BIND_AUTO_CREATE);
1
2
3
4
5
6
7
8
9
解綁:
unbindService(testServiceConnection);
1
可通信服務(wù)與不可通信服務(wù)
可通信服務(wù)使用步驟
可通信服務(wù)使用步驟1: 新建子類繼承Service類和定義一個Binder。
package com.ti.myapplication; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class CommunicationService extends Service { private CommunicationBinder mBinder = new CommunicationBinder("可通信Service"); public CommunicationService() { } @Override public void onCreate() { super.onCreate(); Log.d("可通信Service#","onCreate創(chuàng)建服務(wù)"); } // 可通信Service在綁定服務(wù)時,不會執(zhí)行onStartCommand方法 @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("可通信Service#","onStartCommand開始服務(wù)"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { Log.d("可通信Service#","onBind綁定服務(wù)"); return mBinder; } @Override public boolean onUnbind(Intent intent) { Log.d("可通信Service#","onUnbind解綁服務(wù)"); return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); Log.d("可通信Service#","onDestroy銷毀服務(wù)"); } //新建一個子類繼承自Binder類 class CommunicationBinder extends Binder { private String name; public CommunicationBinder(String name){ this.name = name; } public void service_connect_Activity() { Log.d("","Service關(guān)聯(lián)了Activity,并在Activity執(zhí)行了Service的方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; } } }
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
可通信服務(wù)使用步驟2: 在AndroidManifest.xml中注冊服務(wù)
1
2
3
4
5
6
7
8
9
10
11
12
13
可通信服務(wù)使用步驟3: 準備好ServiceConnection
private CommunicationService.CommunicationBinder myBinder; // 創(chuàng)建ServiceConnection的匿名類 private ServiceConnection connection = new ServiceConnection() { // 重寫onServiceConnected()方法和onServiceDisconnected()方法 // 在Activity與Service建立關(guān)聯(lián)和解除關(guān)聯(lián)的時候調(diào)用 @Override public void onServiceDisconnected(ComponentName name) { } //在Activity與Service解除關(guān)聯(lián)的時候調(diào)用 @Override public void onServiceConnected(ComponentName name, IBinder service) { // 實例化Service的內(nèi)部類myBinder // 通過向下轉(zhuǎn)型得到了MyBinder的實例 myBinder = (CommunicationService.CommunicationBinder) service; // 在Activity調(diào)用Service類的方法 myBinder.service_connect_Activity(); } };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
可通信服務(wù)使用步驟4: 綁定服務(wù)
package com.ti.myapplication; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class MainActivity extends AppCompatActivity { private CommunicationService.CommunicationBinder myBinder; // 創(chuàng)建ServiceConnection的匿名類 private ServiceConnection connection = new ServiceConnection() { // 重寫onServiceConnected()方法和onServiceDisconnected()方法 // 在Activity與Service建立關(guān)聯(lián)和解除關(guān)聯(lián)的時候調(diào)用 @Override public void onServiceDisconnected(ComponentName name) { } //在Activity與Service解除關(guān)聯(lián)的時候調(diào)用 @Override public void onServiceConnected(ComponentName name, IBinder service) { // 實例化Service的內(nèi)部類myBinder // 通過向下轉(zhuǎn)型得到了MyBinder的實例 myBinder = (CommunicationService.CommunicationBinder) service; // 在Activity調(diào)用Service類的方法 myBinder.service_connect_Activity(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.bind_service).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 構(gòu)建綁定服務(wù)的Intent對象 Intent bindServiceIntent = new Intent(MainActivity.this,CommunicationService.class); // 第一個參數(shù):Intent對象 // 第二個參數(shù):上面創(chuàng)建的ServiceConnection實例 // 第三個參數(shù):標志位 // 這里傳入BIND_AUTO_CREATE表示在Activity和Service建立關(guān)聯(lián)后自動創(chuàng)建Service // 這會使得MyService中的onCreate()方法得到執(zhí)行,但onStartCommand()方法不會執(zhí)行 bindService(bindServiceIntent,connection,BIND_AUTO_CREATE); } }); findViewById(R.id.unbind_service).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 調(diào)用unbindService()解綁服務(wù) // 參數(shù)是上面創(chuàng)建的Serviceconnection實例 unbindService(connection); } }); } }
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
測試結(jié)果:
2019-07-22 20:09:59.662 17540-17540/com.ti.myapplication D/可通信Service#: onCreate創(chuàng)建服務(wù) 2019-07-22 20:09:59.663 17540-17540/com.ti.myapplication D/可通信Service#: onBind綁定服務(wù) 2019-07-22 20:10:01.067 17540-17540/com.ti.myapplication D/可通信Service#: onUnbind解綁服務(wù) 2019-07-22 20:10:01.068 17540-17540/com.ti.myapplication D/可通信Service#: onDestroy銷毀服務(wù)
1
2
3
4
Service與Thread
它們沒有任何的關(guān)系,但它們常常在一起組合著使用。
Service與Thread的相同點:都是用于執(zhí)行異步操作的。
Service與Thread的不同點:
Service運行在主線程,Thread運行在工作線程
Servcie運行在主線程,不依賴UI/Activity,Thread則要依賴在某個Activity上。
Service的生命周期
遠程服務(wù)的講解,獨立成一章《遠程服務(wù)Service & AIDL & IPC》
關(guān)于本地服務(wù)、可通信服務(wù)、前臺服務(wù)的使用的demo已上傳Github。歡迎下載學習!
Android 任務(wù)調(diào)度 網(wǎng)站
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。