Android 使用IntentService
本篇文章還是在Android 使用前臺服務都知道服務中的程式碼都是預設執行在主執行緒當中的,如果直接在服務裡去處理一些耗時的邏輯,就很容易出現ANR(Application Not Responding)的情況,所以這個時候就需要用到Android多執行緒程式設計的技術了,我們應該在服務的每個具體的方法裡開啟一個子執行緒,然後在這裡去處理那些耗時的邏輯,因此,一個比較標準的服務就可以寫成如下形式:
public class MyService extends Service { ... @Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { //處理具體的邏輯 } }).start(); return super.onStartCommand(intent, flags, startId); } ... }
但是,這種服務一旦啟動之後,就會一直處於執行狀態,必須呼叫stopService()或者stopSelf()方法才能讓服務停止下來,所以,如果想要實現讓一個服務在執行完畢後自動停止的功能,就可以這樣寫:
public class MyService extends Service { ... @Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { //處理具體的邏輯 stopSelf(); } }).start(); return super.onStartCommand(intent, flags, startId); } ... }
雖說這種寫法並不複雜,但是總會有一些人忘記開啟執行緒,或者忘記呼叫stopSelf()方法,為了可以簡單的建立一個非同步的,會自動停止的服務,Android專門提供了一個IntentService類,這個類就很好的解決了前面所提到的兩種尷尬,下面我們就來看一下它的用法.
新建一個MyIntentService類繼承自IntentService,程式碼如下:
public class MyIntentService extends IntentService { private static final String TAG = "MyIntentService"; public MyIntentService() { super("MyIntentService");//呼叫父類的有參建構函式 } @Override protected void onHandleIntent(@Nullable Intent intent) { //列印當先執行緒的id Log.d(TAG, "onHandleIntent: " + "Thread id is " + Thread.currentThread().getId()); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: executed"); } }
這裡首先要提供一個午餐的建構函式,並且必須在其內部呼叫父類的有參建構函式,然後要在子類中去實現onHandleIntent()這個抽象方法,在這個方法中可以去處理一些具體的邏輯,而且不用擔心ANR的問題,因為這個方法已經是在子執行緒中執行的了,這裡為了證實一下,我們在onHandleIntent()方法中列印了當前執行緒的id,另外根據IntentService的特性,這個服務在執行結束後應該會自動停止的,所以我們又重寫了onDestroy()方法,在這裡也列印了一行日誌,以證實服務是不是停止掉了.
接下來修改activity_main.xml中的程式碼,加入一個用於啟動MyIntentService這個服務的按鈕,如下:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.servicetest.MainActivity"> ... <Button android:id="@+id/start_intent_service" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start IntentService" android:textAllCaps="false" app:layout_constraintTop_toBottomOf="@id/unbind_service"/> </android.support.constraint.ConstraintLayout>
然後修改MainActivity中的程式碼,如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private static final String TAG = "MainActivity"; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... Button startIntentService = findViewById(R.id.start_intent_service); startIntentService.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ ... case R.id.start_intent_service: //列印主執行緒的id Log.d(TAG, "onClick: " + "Thread id is " + Thread.currentThread().getId()); Intent intentService = new Intent(this,MyIntentService.class); startService(intentService); break; default: break; } } }
可以看到,我們在Start IntentService按鈕的點選事件裡面去啟動MyIntentService這個服務,並在這裡列印了一下主執行緒的id,稍後用於和IntentService進行比對,你會發現,其實IntentService的用法和普通的服務沒什麼兩樣.
最後不要忘記,服務都需要在AndroidManifest.xml裡進行註冊,如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.servicetest"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> ... <service android:name=".MyIntentService" /> </application> </manifest>
現在重新執行一下程式,如圖:
點選Start IntentService按鈕後,觀察logcat中列印的日誌,如圖:
可以看到,不僅MyIntentService和MainActivity所在的執行緒id不一樣,而且onDestroy()方法也得到了執行,說明MyIntentService在執行完畢後確實自動停止了,集開啟執行緒和自動停止於一身.
相關文章
- Android IntentService 的使用和解析AndroidIntent
- Android IntentServiceAndroidIntent
- Android中IntentService的原理及使用AndroidIntent
- Android IntentService 工作原理AndroidIntent
- IntentService的使用Intent
- Android中IntentService的使用及其原始碼解析AndroidIntent原始碼
- Android面試相關 - IntentServiceAndroid面試Intent
- Android IntentService使用全面介紹及原始碼解析AndroidIntent原始碼
- Android中IntentService原始碼分析AndroidIntent原始碼
- Android多執行緒之IntentServiceAndroid執行緒Intent
- Android IntentService完全解析 當Service遇到HandlerAndroidIntent
- IntentServiceIntent
- Android後臺任務(HandlerThread、AsyncTask、IntentService)AndroidthreadIntent
- IntentService小酌Intent
- Android四大元件之Service,以及IntentServiceAndroid元件Intent
- 理解 IntentService 原理Intent
- IntentService原始碼Intent原始碼
- IntentService簡介Intent
- Android Service和IntentService知識點詳細總結AndroidIntent
- 2018.03.16、Android-IntentService學習筆記AndroidIntent筆記
- IntentService,用完即走Intent
- 淺談IntentService原理分析Intent
- 從原始碼分析IntentService原始碼Intent
- IntentService 和 HandlerThread 的原理Intentthread
- HandlerThread和IntentService原始碼解析threadIntent原始碼
- 活兒好又不糾纏的 IntentServiceIntent
- 用IntentService 與ResultReceiver連線web serviceIntentWeb
- 看完這一篇,再也不怕面試官問到IntentService的原理面試Intent
- Android Bitmap 使用Android
- Android FragmentManager使用AndroidFragment
- Android Iterator 使用Android
- [android]android-am命令的使用Android
- Android 幀動畫使用Android動畫
- Android PopUpWindow基本使用Android
- android SQLite的使用AndroidSQLite
- Android:Glide使用AndroidIDE
- Android使用iconfontAndroid
- android CoordinatorLayout使用Android