日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 4 学习(19):Services

發布時間:2023/12/18 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 4 学习(19):Services 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考《Professional?Android?4?Development

?

Services

Serviceinvisible的,因此其優先級不高于visibleActivity,之所以說不高于,是因為我們可以設置Service為在前臺運行。

創建Service

Android提供了Service抽象類,繼承它便可以創建一個Service類:

?

import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyService extends Service {@Overridepublic void onCreate() {super.onCreate();// TODO: Actions to perform when service is created.}@Overridepublic IBinder onBind(Intent intent) {// TODO: Replace with service binding implementation.return null;} }

?

創建Service類之后,還需要在Manifest里面注冊:

?

<service android:enabled=”true” android:name=”.MyService” android:permission=”com.paad.MY_SERVICE_PERMISSION”/>

?

若要默認只有自己的程序可以使用這個Service,需要添加Android:permission屬性。其他Application若要使用這個服務,需要加入這個permission

執行Service

ServicestartService()方法調用時,即可引起onStartCommand方法的調用,因此需要重寫Service中的onStartCommand方法,并且onStartCommand方法可能會被多次調用。onStartCommand()方法將返回一個int值,用于指定當Serviceruntime殺掉又重啟的時,系統該如何響應:

?

@Override public int onStartCommand(Intent intent, int flags, int startId) {startBackgroundTask(intent, startId);return Service.START_STICKY; }

?

重啟Service

onStartCommand()方法可以返回這些參數,它們的意義是:

START_STICKY:如果service進程被kill掉,保留service的狀態為開始狀態,但不保留遞送的intent對象。隨后系統會嘗試重新創建service,由于服務狀態為開始狀態,所以創建服務后一定會調用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那么參數Intent將為null。

START_NOT_STICKY:“非粘性的”。如果在執行完onStartCommand后,服務被異常kill掉,系統不會自動重啟該服務。
START_REDELIVER_INTENT:使用這個返回值時,如果未執行完onStartCommand,服務在調用stopSelf之前被kill掉,系統會自動重啟該服務,并將Intent的值傳入。

參考:http://www.krislq.com/2013/05/android-class-return-value-of-onstartcommand/

啟動和停止服務

調用startService方法可以啟動服務:

?

private void explicitStart() {// Explicitly start My ServiceIntent intent = new Intent(this, MyService.class);// TODO Add extras if required.startService(intent); } private void implicitStart() {// Implicitly start a music ServiceIntent intent = new Intent(MyMusicService.PLAY_ALBUM);intent.putExtra(MyMusicService.ALBUM_NAME_EXTRA, “United”);intent.putExtra(MyMusicService.ARTIST_NAME_EXTRA, “Pheonix”);startService(intent); }

?

調用stopService方法可以停止服務:

?

// Stop a service explicitly. stopService(new Intent(this, MyService.class)); // Stop a service implicitly. Intent intent = new Intent(MyMusicService.PLAY_ALBUM); stopService(intent);

?

服務自殺

服務內部調用stopSelf方法,可以停止該服務。

綁定ServiceActivity

首先,Service要實現IBind接口:

?

@Override public IBinder onBind(Intent intent) {return binder; } public class MyBinder extends Binder {MyMusicService getService() {return MyMusicService.this;} } private final IBinder binder = new MyBinder();

?

ServiceConnection類用于表示ServiceActivity的綁定,每個綁定都需要創建一個ServiceConnection

?

// Reference to the service private MyMusicService serviceRef; // Handles the connection between the service and activity private ServiceConnection mConnection = new ServiceConnection() {public void onServiceConnected(ComponentName className, IBinder service) {// Called when the connection is made.serviceRef = ((MyMusicService.MyBinder)service).getService();}public void onServiceDisconnected(ComponentName className) {// Received when the service unexpectedly disconnects.serviceRef = null;} };

?

最后,調用bindService方法,傳入用于啟動ServiceIntentServiceConnection和標志位:

?

// Bind to the service Intent bindIntent = new Intent(MyActivity.this, MyMusicService.class); bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);

?

通常情況下,Android應用在自己的內存空間中運行,并不共享內存。若要與其他進程通信,可以使用廣播,或在Intent中添加Bundle參數啟動其他Service的方法。如果需要更緊密的通信,可以使用Android?Interface?Defi?nition?Language(AIDL)。AIDL使用OS級別的簡單變量定義了接口,可以跨應用傳遞對象。

?

創建前臺服務

?

使用startForeground方法啟動服務,可以使服務獲得與Visible?Activity相同的優先級,例如:

?

private void startPlayback(String album, String artist) {int NOTIFICATION_ID = 1;// Create an Intent that will open the main Activity if the notification is clicked.Intent intent = new Intent(this, MyActivity.class);PendingIntent pi = PendingIntent.getActivity(this, 1, intent, 0);// Set the Notification UI parametersNotification notification = new Notification(R.drawable.icon, “Starting Playback”, System.currentTimeMillis());notification.setLatestEventInfo(this, album, artist, pi);// Set the Notification as ongoingnotification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;// Move the Service to the ForegroundstartForeground(NOTIFICATION_ID, notification); }

?

使用stopForeground方法可以取消Service的前臺屬性:

?

public void pausePlayback() {// Move to the background and remove the NotificationstopForeground(true); }

?

使用后臺線程

ServiceActivity一樣,也是在主線程中運行的,為了更好地響應用戶,我們需要使用后臺線程的方式執行ServiceAndroid提供了兩個抽象類來幫助我們實現:AsyncTaskIntentService

使用AsyncTask

AsyncTask不僅能幫助我們將費時操作放到后臺執行,還可以實現和UI線程的同步。AsyncTask適合執行那些耗時比較短并且和UI線程有交互的任務,對于耗時較久的任務(例如下載),使用Service更為合適。需要注意的是AsyncTask在應用restart之后會被cancel掉。

?

private class MyAsyncTask extends AsyncTask<String, Integer, String> { @Override protected String doInBackground(String... parameter) { // Moved to a background thread. String result = “”; int myProgress = 0; int inputLength = parameter[0].length(); // Perform background processing task, update myProgress] for (int i = 1; i <= inputLength; i++) { myProgress = i; result = result + parameter[0].charAt(inputLength-i); try { Thread.sleep(100); } catch (InterruptedException e) { } publishProgress(myProgress); } // Return the value to be passed to onPostExecute return result; } @Override protected void onProgressUpdate(Integer... progress) { // Synchronized to UI thread. // Update progress bar, Notification, or other UI elements asyncProgress.setProgress(progress[0]); } @Override protected void onPostExecute(String result) { // Synchronized to UI thread. // Report results via UI update, Dialog, or notifications asyncTextView.setText(result); } }

?

使用AsyncTask,首先要創建一個AsyncTask的子類類并實現doInBackgroundonProgressUpdateonPostExecute方法。這三個方法的說明:

  • doInBackground:?這個方法用于執行需要在后臺線程中長期運行的操作,可以通過publishProgress方法傳遞參數給onProgressUpdate;在這個方法執行完畢之后,此方法將返回值傳遞給onProgressUpdate。
  • onProgressUpdate:?接收publishProgress方法傳入的參數,更新UI
  • onPostExecute:?doInBackground執行結束后,將返回值傳入此方法。

執行AsyncTask

String input = “redrum ... redrum”; new MyAsyncTask().execute(input);

Intent?Service簡介

IntentService可以通過傳入Intent參數調用,傳入的Intent將進入一個隊列中被異步執行。IntentService封裝了消息的異步處理,后臺線程創建以及與UI線程的同步。繼承IntentService類并實現onHandleIntent方法,即可創建一個Intent?Service

?

import android.app.IntentService; import android.content.Intent; public class MyIntentService extends IntentService {public MyIntentService(String name) {super(name);// TODO Complete any required constructor tasks.}@Overridepublic void onCreate() {super.onCreate();// TODO: Actions to perform when service is created.}@Overrideprotected void onHandleIntent(Intent intent) {// This handler occurs on a background thread. TODO The time consuming task should be implemented here.// Each Intent supplied to this IntentService will be processed consecutively here. When all incoming Intents have been processed the Service will terminate itself.} }

?

Loader簡介

Loader是一個抽象類,封裝了異步加載數據的最佳實踐,最典型的就是CursorLoader了。Android中創建Loader類的簡單方法是繼承AsyncTaskLoader類,并實現這兩個功能:

  • 異步加載數據
  • 監測數據源的變化并及時更新

手動創建線程及GUI線程同步

盡管AsyncTaskIntent?Service提供了簡單易用的異步類封裝,但我們也可以創建自定義的異步線程:

?

// This method is called on the main GUI thread. private void backgroundExecution() {// This moves the time consuming operation to a child thread.Thread thread = new Thread(null, doBackgroundThreadProcessing, “Background”);thread.start(); } // Runnable that executes the background processing method. private Runnable doBackgroundThreadProcessing = new Runnable() {public void run() {backgroundThreadProcessing();} }; // Method which does some processing in the background. private void backgroundThreadProcessing() { // [ ... Time consuming operations ... ] }

?

GUI線程同步:

?

runOnUiThread方法會在UI線程執行:

?

runOnUiThread(new Runnable() {public void run() {// Update a View or other Activity UI element.} });

?

此外,可以使用Handler類更新UI線程:

?

//This method is called on the main GUI thread. private void backgroundExecution() {// This moves the time consuming operation to a child thread.Thread thread = new Thread(null, doBackgroundThreadProcessing, “Background”);thread.start(); } // Runnable that executes the background processing method. private Runnable doBackgroundThreadProcessing = new Runnable() {public void run() {backgroundThreadProcessing();} }; // Method which does some processing in the background. private void backgroundThreadProcessing() { // [ ... Time consuming operations ... ] // Use the Handler to post the doUpdateGUI // runnable on the main UI thread.handler.post(doUpdateGUI); } //Initialize a handler on the main thread. private Handler handler = new Handler(); // Runnable that executes the updateGUI method. private Runnable doUpdateGUI = new Runnable() {public void run() {updateGUI();} }; // This method must be called on the UI thread. private void updateGUI() { // [ ... Open a dialog or modify a GUI element ... ] }

?

Handler類還可以使用postDelayedpostAtTime實現推遲運行和推遲指定時間運行:

?

// Post a method on the UI thread after 1sec. handler.postDelayed(doUpdateGUI, 1000); // Post a method on the UI thread after the device has been in use for 5mins. int upTime = 1000*60*5; handler.postAtTime(doUpdateGUI, SystemClock.uptimeMillis()+upTime);

?

使用ALARMS

Timer不太,Alarms屬于系統服務,獨立于應用程序。即使應用程序為啟動,也可以使用Alarms啟動應用程序并獲取其服務,這樣不僅減少了耦合,也減少了系統資源的占用。AndroidAlarms常與Broadcast?Receiver一起使用。創建Alarm之前,首先要創建AlarmManager

?

AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);

?

創建,設置和取消ALARMS

創建Alarm需要這些參數:alarm類型,觸發時間,Alarm將要觸發的Pending?Intent。目前Alarm類型有這些:

  • RTC_WAKEUP:在指定時間啟動指定Pending?Intent,可以喚醒sleep中的設備。
  • RTC在指定時間啟動指定Pending?Intent,但不能喚醒sleep中的設備。
  • ELAPSED_REALTIME:在某段時間后啟動指定的Pending?Intent,某段時間是從設備啟動但還沒有喚醒設備算起。
  • ELAPSED_REALTIME_WAKEUP:?這個和ELAPSED_REALTIME的區別沒搞明白,以后遇到了再查吧。

下面是一個10秒后啟動Pending?IntentAlarm示例:

?

AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); // Set the alarm to wake the device if sleeping. int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP; // Trigger the device in 10 seconds. long timeOrLengthofWait = 10000; // Create a Pending Intent that will broadcast and action String ALARM_ACTION = “ALARM_ACTION”; Intent intentToFire = new Intent(ALARM_ACTION); PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0); // Set the alarm alarmManager.set(alarmType, timeOrLengthofWait, alarmIntent);

?

取消Alarm

alarmManager.cancel(alarmIntent);

這里的alarmIntent是指使用Alarm啟動的Pending?Intent

?

創建可重復的Alarm

?

使用setRepeating或setInexactRepeating方法替代前面的set方法,并傳遞響應的參數進去,就可以實現可重復的Alarm

?

相比setRepeating,setInexactRepeating更省電,但不能指定某個具體的時間間隔。

?

setInexactRepeating可以接收的時間間隔參數:

?

  • INTERVAL_FIFTEEN_MINUTES
  • INTERVAL_HALF_HOUR
  • INTERVAL_HOUR
  • INTERVAL_HALF_DAY
  • INTERVAL_DAY

?

下面這個例子指定半小時后啟動Alarm,然后每隔半小時啟動一次:

?

// Get a reference to the Alarm Manager AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); // Set the alarm to wake the device if sleeping. int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP; // Schedule the alarm to repeat every half hour. long timeOrLengthofWait = AlarmManager.INTERVAL_HALF_HOUR; // Create a Pending Intent that will broadcast and action String ALARM_ACTION = “ALARM_ACTION”; Intent intentToFire = new Intent(ALARM_ACTION); PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0); // Wake up the device to fire an alarm in half an hour, and every half-hour after that. alarmManager.setInexactRepeating(alarmType, timeOrLengthofWait, timeOrLengthofWait, alarmIntent);

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

轉載于:https://www.cnblogs.com/jubincn/p/3521452.html

總結

以上是生活随笔為你收集整理的Android 4 学习(19):Services的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。