android-Service和Thread的区别
1.服務不是單一的進程。服務沒有自己的進程,應用程序可以不同,服務運行在相同的進程中。
2.服務不是線程。可以在線程中工作。
一.在應用中,如果是長時間的在后臺運行,而且不需要交互的情況下,使用服務。
同樣是在后臺運行,不需要交互的情況下,如果只是完成某個任務,之后就不需要運行,而且可能是多個任務,需需要長時間運行的情況下使用線程。
二.如果任務占用CPU時間多,資源大的情況下,要使用線程。
?
servie是系統的組件,它由系統進程托管(servicemanager);它們之間的通信類似于client和server,是一種輕量級的ipc通信,這種通信的載體是binder,它是在linux層交換信息的一種ipc。而thread是由本應用程序托管。
?
1).?Thread:Thread?是程序執行的最小單元,它是分配CPU的基本單位。可以用Thread?來執行一些異步的操作。
?
2).?Service:Service?是android的一種機制,當它運行的時候如果是Local?Service,那么對應的Service?是運行在主進程的main?線程上的。如:onCreate,onStart?這些函數在被系統調用的時候都是在主進程的main?線程上運行的。如果是Remote?Service,那么對應的Service?則是運行在獨立進程的main?線程上。
?
既然這樣,那么我們為什么要用Service?呢?其實這跟android?的系統機制有關,我們先拿Thread?來說。Thread?的運行是獨立于Activity?的,也就是說當一個Activity?被finish?之后,如果你沒有主動停止Thread?或者Thread?里的run?方法沒有執行完畢的話,Thread?也會一直執行。因此這里會出現一個問題:當Activity?被finish?之后,你不再持有該Thread?的引用。另一方面,你沒有辦法在不同的Activity?中對同一Thread?進行控制。
?
舉個例子:如果你的Thread?需要不停地隔一段時間就要連接服務器做某種同步的話,該Thread?需要在Activity?沒有start的時候也在運行。這個時候當你start?一個Activity?就沒有辦法在該Activity?里面控制之前創建的Thread。因此你便需要創建并啟動一個Service?,在Service?里面創建、運行并控制該Thread,這樣便解決了該問題(因為任何Activity?都可以控制同一Service,而系統也只會創建一個對應Service?的實例)。
?
因此你可以把Service?想象成一種消息服務,而你可以在任何有Context?的地方調用Context.startService、Context.stopService、Context.bindService,Context.unbindService,來控制它,你也可以在Service?里注冊BroadcastReceiver,在其他地方通過發送broadcast?來控制它,當然這些都是Thread?做不到的。
---------------------------------------------------------------------------------
?
廣播接收者(BroadcastReceiver)用于接收廣播Intent,廣播Intent的發送是通過調用Context.sendBroadcast()、Context.sendOrderedBroadcast()來實現的。通常一個廣播Intent可以被訂閱了此Intent的多個廣播接收者所接收,這個特性跟JMS中的Topic消息接收者類似。要實現一個廣播接收者方法如下:
第一步:繼承BroadcastReceiver,并重寫onReceive()方法。
public?class?IncomingSMSReceiver?extends?BroadcastReceiver?{
@Override?public?void?onReceive(Context?context,?Intent?intent)?{
}
}
第二步:訂閱感興趣的廣播Intent,訂閱方法有兩種:
第一種:使用代碼進行訂閱
IntentFilter?filter?=?new?IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver?receiver?=?new?IncomingSMSReceiver();
registerReceiver(receiver,?filter);
第二種:在AndroidManifest.xml文件中的<application>節點里進行訂閱:
<receiver?android:name=".IncomingSMSReceiver">
<intent-filter>
<action?android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
如果你想別人接收到的短信,達到你不可告人的目的,那么使用BroadcastReceiver
當系統收到短信時,會發出一個廣播Intent,Intent的action名稱為、
如果要短信終止廣播就要配置上你的廣播接收者的級別
<intent-filter?android:priority="100"?>
<action?android:name="android.provider.Telephony.SMS_RECEIVED"?/>
</intent-filter>
android.provider.Telephony.SMS_RECEIVED,該Intent存放了系統接收到的短信內容,我們使用名稱“pdus”即可從Intent中獲取到短信內容。
在AndroidManifest.xml文件中的<application>節點里對接收到短信的廣播Intent進行訂閱:
<receiver?android:name=".你的receiver名稱">
<intent-filter><action?android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter></receiver>
在AndroidManifest.xml文件中添加以下權限:
<uses-permission?android:name="android.permission.RECEIVE_SMS"/><!--?接收短信權限?-->
<uses-permission?android:name="android.permission.SEND_SMS"/><!--?發送短信權限?-->
廣播接收者的響應性
在Android中,每次廣播消息到來時都會創建BroadcastReceiver實例并執行onReceive()?方法,?onReceive()?方法執行完后,BroadcastReceiver?的實例就會被銷毀。當onReceive()?方法在10秒內沒有執行完畢,Android會認為該程序無響應。所以在BroadcastReceiver里不能做一些比較耗時的操作,否側會彈出ANR(Application?No?Response)錯誤對話框。如果需要完成一項比較耗時的工作,應該通過發送Intent給Service,由Service來完成。這里不能使用子線程來解決,因為BroadcastReceiver的生命周期很短,子線程可能還沒有結束BroadcastReceiver就先結束了。BroadcastReceiver一旦結束,此時BroadcastReceiver所在的進程很容易在系統需要內存時被優先殺死,因為它屬于空進程(沒有任何活動組件的進程)。如果它的所在進程被殺死,那么正在工作的子線程也會被殺死。所以采用子線程來解決是不可靠的。
public?class?IncomingSMSReceiver?extends?BroadcastReceiver?{
@Override?public?void?onReceive(Context?context,?Intent?intent)?{
//發送Intent啟動服務,由服務來完成比較耗時的操作
Intent?service?=?new?Intent(context,?XxxService.class);
context.startService(service);
}
除了短信到來廣播Intent,Android還有很多廣播Intent,如:開機啟動、電池電量變化、時間已經改變等廣播Intent。
接收電池電量變化廣播Intent?,在AndroidManifest.xml文件中的<application>節點里訂閱此Intent:
<receiver?android:name=".IncomingSMSReceiver">
<intent-filter>
<action?android:name="android.intent.action.BATTERY_CHANGED"/>
</intent-filter>
</receiver>
接收開機啟動廣播Intent,在AndroidManifest.xml文件中的<application>節點里訂閱此Intent:
<receiver?android:name=".IncomingSMSReceiver">
<intent-filter>
<action?android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
并且要進行權限聲明:
<uses-permission?android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
廣播接收者補充
廣播分兩種?
有序廣播?按照廣播的優先級?發給相對應的廣播接收者-1000-1000?激活廣播通過onrecve方法處理
無序廣播
有序廣播有一個特例
sendOrderedBroadcast(intent,?receiverPermission,?resultReceiver,?scheduler,?initialCode,?initialData,?initialExtras);
resultReceiver?廣播接受者?如果我們顯示的指定了廣播接收者?
無論如何?都會接受廣播?無法通過abortBroadcast();的方法終止廣播
比如撥打電話有個out_goingcall?的廣播是指定廣播接收者的無法通過abortBroadcast()方法終止的,但是是可以將撥打的電話號碼數據清空置為null,setResultData(null)就無法撥打電話
?
另外一種特殊的廣播sendStickyBroadcast(intent)?//?陰魂不散的廣播?
一般廣播事件發送完畢被廣播接受者接收到onReceive執行完畢后廣播接收者的生命周期就結束了?這個會保持長時間的停留直到廣播事件結束完畢
例如系統的Wifi,網卡狀態的改變要一定的時間,保證網絡狀態更新完畢后才結束
代碼中注冊,如果代碼沒有執行,就接受不到廣播事件
什么時候使用廣播,例如sdcard新增圖片的時候是無法顯示到圖庫的當sdcard被掛載狀態發生改變才會重新加載sdcard的數據
這時可以發送一個sd掛載的通知,通知系統的gallery去獲取到新的圖片.
Intent?intent?=?newIntent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
總結
以上是生活随笔為你收集整理的android-Service和Thread的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何扩展Linux的ip_conntra
- 下一篇: OpenSSL“心脏出血”漏洞爆发和修复