Android面试题Service,Android面试题-IntentService源码分析
自定義控件
聯網
工具
數據庫
源碼分析相關面試題
Activity相關面試題
Service相關面試題
與XMPP相關面試題
與性能優化相關面試題
與登錄相關面試題
與開發相關面試題
與人事相關面試題
人事面試寶典
IntentService是繼承于Service并處理異步請求的一個類,在IntentService內有一個工作線程來處理耗時操作,啟動IntentService的方式和啟動傳統Service一樣,同時,當任務執行完后,IntentService會自動停止,而不需要我們去手動控制。另外,可以啟動IntentService多次,而每一個耗時操作會以工作隊列的方式在IntentService的onHandleIntent回調方法中執行,并且,每次只會執行一個工作線程,執行完第一個再執行第二個,以此類推。
而且,所有請求都在一個單線程中,不會阻塞應用程序的主線程(UI Thread),同一時間只處理一個請求。
IntentService有什么好處呢?
1)我們省去了在Service中手動開線程的麻煩,
2)當操作完成時,我們不用手動停止Service。
接下來讓我們來看看如何使用,寫一個Demo來模擬兩個耗時操作,Operation1與Operation2,先執行1,2必須等1執行完才能執行2:
新建工程,新建一個繼承IntentService的類,我這里是IntentServiceDemo.java
public class IntentServiceDemo extends IntentService {
public IntentServiceDemo() {
//必須實現父類的構造方法
super("IntentServiceDemo");
}
@Override
public IBinder onBind(Intent intent) {
System.out.println("onBind");
return super.onBind(intent);
}
@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
System.out.println("onStart");
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void setIntentRedelivery(boolean enabled) {
super.setIntentRedelivery(enabled);
System.out.println("setIntentRedelivery");
}
@Override
protected void onHandleIntent(Intent intent) {
//Intent是從Activity發過來的,攜帶識別參數,根據參數不同執行不同的任務
System.out.println("currentThread()=" + Thread.currentThread().getName());
String action = intent.getExtras().getString("param");
if (action.equals("oper1")) {
System.out.println("Operation1");
}else if (action.equals("oper2")) {
System.out.println("Operation2");
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
}
}
我把生命周期方法全打印出來了,待會我們來看看它執行的過程是怎樣的。接下來是Activity,在Activity中來啟動IntentService:
public class TestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//可以啟動多次,每啟動一次,就會新建一個work thread,但IntentService的實例始終只有一個
//Operation 1
Intent startServiceIntent = new Intent("com.test.intentservice");
Bundle bundle = new Bundle();
bundle.putString("param", "oper1");
startServiceIntent.putExtras(bundle);
startService(startServiceIntent);
//Operation 2
Intent startServiceIntent2 = new Intent("com.test.intentservice");
Bundle bundle2 = new Bundle();
bundle2.putString("param", "oper2");
startServiceIntent2.putExtras(bundle2);
startService(startServiceIntent2);
}
}
最后,別忘了配置Service,因為它繼承于Service,所以,它還是一個Service,一定要配置,否則是不起作用的
最后來看看執行結果:
從結果可以看到,onCreate方法只執行了一次,而onStartCommand和onStart方法執行了兩次,開啟了兩個Work Thread,這就證實了之前所說的,啟動多次,但IntentService的實例只有一個,這跟傳統的Service是一樣的。Operation1也是先于Operation2打印,并且我讓兩個操作間停頓了2s,最后是onDestroy銷毀了IntentService。
IntentService 源碼分析
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
源碼可知:
1)實際上是使用了一個 HandlerThread 來維護線程的,
2) HandleThread 中,內部已經維護一個 Looper,這里直接使用 HandlerThread 的 Looper 對象,便于在 IntentService 中去維護消息隊列,
3)創建的 mServiceHandler 是屬于 HandleThread 這個 WorkerThread 的。
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
源碼可知:
1)直接把消息交給 onHandleIntent() 方法去執行具體的業務邏輯
2)執行完成之后,立即調用 stopSelf() 方法停止自己
接下來分析start源碼
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
源碼可知
1)在 onStartCommand() 中直接調用了 onStart() 方法
2)而上面 stopSelf() 方法使用的 startId 來停止當前的此次任務服務。
3)而 Service 如果被啟動多次,就會存在多個 startId ,當所有的 startId 都被停止之后,才會調用 onDestory() 自我銷毀。
我們在看看HandlerThread啟動之后的源碼
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
源碼可知
1)run方法里面添加了鎖,這也解釋了為什么多次 start 同一個 IntentService 它會順序執行,全部執行完成之后,再自我銷毀。
歡迎關注微信公眾號,長期推薦技術文章和技術視頻
微信公眾號名稱:Android干貨程序員
總結
以上是生活随笔為你收集整理的Android面试题Service,Android面试题-IntentService源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android.mk 比较字变量,粉丝投
- 下一篇: android 仿京东地址选择_Andr