編輯:關於Android編程
官方解釋如下:
//IntentService定義的三個基本點:是什麼?怎麼用?如何work?*/
1、IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. 2、Clients send requests through startService(Intent) calls;
3、the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
//解釋了IntentService的好處,以及How to use IntentService*/
This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
1、IntentService是Service類的子類,用來處理異步請求。
2、客戶端可以通過startService(Intent)方法傳遞請求給IntentService
3、IntentService在onCreate()函數中通過HandlerThread單獨開啟一個線程來處理所有Intent請求對象(通過startService的方式發送過來的)所對應的任務,這樣以免事務處理阻塞主線程。
4、執行完所一個Intent請求對象所對應的工作之後,如果沒有新的Intent請求達到,則自動停止Service;否則執行下一個Intent請求所對應的任務。
5、IntentService在處理事務時,還是采用的Handler方式,創建一個名叫ServiceHandler的內部Handler,並把它直接綁定到HandlerThread所對應的子線程。 ServiceHandler把處理一個intent所對應的事務都封裝到叫做onHandleIntent的虛函數;因此我們直接實現虛函數onHandleIntent,再在裡面根據Intent的不同進行不同的事務處理就可以了。
This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().
1、該函數用於針對Intent的不同進行不同的事務處理.執行完所一個Intent請求對象所對應的工作之後,如果沒有新的Intent請求達到,
則自動停止Service;否則ServiceHandler會取得下一個Intent請求傳人該函數來處理其所對應的任務。
2、所有請求都在一個單線程中,不會阻塞應用程序的主線程(UI Thread),但是同一時間只處理一個請求。
IntentService的特點:
1、IntentService是借助於消息隊列實現的,所以任務的執行順序就是一個queue的形式;
2、由於是單線程(一個工作線程),所以所有的任務需要排隊執行;/
3、避免了我們再去創建線程和管理service的結束工作;
基於以上,IntentService與Service比較的好處有:
第一,使用方便,代碼簡潔,不再需要我們自己像Service裡面還要去手動創建線程;
第二,當操作完成時,我們不用手動停止Service。
當然,IntentService的缺點也是顯而易見:
由於是單個的worker thread,所以任務需要排隊,不適合大多數的多任務情況;
主要由MainActivity和MyIntentService構成,在MainActivity中啟動服務,並傳遞兩個參數a和b,在MyIntentService中獲取參數,求和,並通過發送廣播的形式向UI返回結果,然後MainActivity在接收到廣播之後更新UI。
代碼如下:
public class MainActivity extends AppCompatActivity {
private LinearLayout ll_container;
private BroadcastReceiver forSumReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("TAG","onReceive ()");
if(intent.getAction()==Constans.ACTION_RESULT){
int a=intent.getIntExtra(Constans.A,0);
int result=intent.getIntExtra(Constans.RESULT,0);
Log.i("TAG","onReceive --result:"+result);
handleResult(a,result);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ll_container= (LinearLayout)findViewById(R.id.ll_container);
Log.i("TEST","MainActivity:"+android.os.Process.myTid());
registerBroadcast();
}
private void handleResult(int a,int result){
TextView textView=(TextView)ll_container.findViewWithTag(a);
String old=textView.getText().toString();
String newText=old.replaceAll(" 正在計算中...",String.valueOf(result)+" 計算Success");
textView.setText(newText);
}
private void registerBroadcast(){
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(Constans.ACTION_RESULT);
registerReceiver(forSumReceiver,intentFilter);
}
private int a=1;
public void addTask(View view){
int b=new Random().nextInt(101)+1;
MyIntentService.startMyIntentService(this,a,b);
TextView textView=new TextView(this);
textView.setText(a+"+"+b+"= "+ " 正在計算中...");
textView.setTag(a);
ll_container.addView(textView);
a++;
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(forSumReceiver);
}
}
public class MyIntentService extends IntentService {
public MyIntentService() {
//必須實現父類的構造方法
super("MyIntentService");
}
@Override
public void onCreate() {
Log.i("TEST","onCreate()");
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
Log.i("TEST","onStart()");
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("TEST","onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.i("TEST", "onBind()");
return super.onBind(intent);
}
@Override
public void onDestroy() {
Log.i("TEST","onDestroy()");
super.onDestroy();
}
@Override
protected void onHandleIntent(Intent intent) {
Log.i("TEST","onHandleIntent():"+android.os.Process.myTid());
if (intent!=null){
String action=intent.getAction();
if(Constans.ACTION_FOR_SUM.equals(action)){
int a=intent.getIntExtra(Constans.A,0);
int b=intent.getIntExtra(Constans.B,0);
int result=a+b;
Log.i("TEST","result: "+result);
handleResult(a,result);
}
}
}
private void handleResult(int a,int result){
try{
//模擬計算耗時
Thread.sleep(3000);
Intent intent=new Intent(Constans.ACTION_RESULT);
intent.putExtra(Constans.RESULT,result);
intent.putExtra(Constans.A,a);
sendBroadcast(intent);
}catch (InterruptedException e){
e.printStackTrace();;
}
}
public static void startMyIntentService(Context context,int a,int b){
Intent intent=new Intent(context,MyIntentService.class);
intent.setAction(Constans.ACTION_FOR_SUM);
intent.putExtra(Constans.A,a);
intent.putExtra(Constans.B,b);
context.startService(intent);
}
}
07-08 10:18:51.579 com.troy.intentservicedemo I/TEST: MainActivity:30060
07-08 10:19:26.009 com.troy.intentservicedemo I/TEST: onCreate()
07-08 10:19:26.009 com.troy.intentservicedemo I/TEST: onStartCommand()
07-08 10:19:26.009 com.troy.intentservicedemo I/TEST: onStart()
07-08 10:19:26.039 com.troy.intentservicedemo I/TEST: onHandleIntent():30223
07-08 10:19:26.039 com.troy.intentservicedemo I/TEST: result: 23
07-08 10:19:29.100 com.troy.intentservicedemo I/TEST: onDestroy()
07-08 10:19:31.839 com.troy.intentservicedemo I/TEST: onCreate()
07-08 10:19:31.849 com.troy.intentservicedemo I/TEST: onStartCommand()
07-08 10:19:31.849 com.troy.intentservicedemo I/TEST: onStart()
07-08 10:19:31.869 com.troy.intentservicedemo I/TEST: onHandleIntent():30305
07-08 10:19:31.869 com.troy.intentservicedemo I/TEST: result: 52
07-08 10:19:34.899 com.troy.intentservicedemo I/TEST: onDestroy()
UI線程的線程ID=30060,而onHandleIntent()的線程ID分別是30223,30305;由此知道onHandleIntent()方法是執行在工作線程中的;
並且IntentService的所有請求如果是在一個生命周期中完成的話,則所有請求是在一個工作線程中順序執行的。否則,是在不同的工作線程中完成。
同時驗證了:執行完所一個Intent請求對象所對應的工作之後,如果沒有新的Intent請求達到,則自動停止Service;
IntentService是Service的子類,擁有Service的所有生命周期方法;同時還有自己的ServiceHandler;
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;//volatile關鍵字保證同步,保證可見性
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
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);
}
}
public IntentService(String name) {//構造方法
super();
mName = name;
}
IntentService 實際上是Looper,Handler,Service 的集合體,他不僅有服務的功能,還有處理和循環消息的功能。
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
IntentService創建時就會創建Handler線程(HandlerThread)並且啟動,然後再得到當前線程的Looper對象來初始化IntentService的mServiceLooper,接著創建mServicehandler對象。
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
當你啟動IntentService的時候,就會產生一條附帶startId和Intent的 Message並發送到MessageQueue中,接下來Looper發現MessageQueue中有Message的時候,就會停止Handler 處理消息。
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
接著調用 onHandleIntent((Intent)msg.obj),這是一個抽象的方法,其實就是我們要重寫實現的方法,我們可以在這個方法裡面處理我們的工作.當任務完成時就會調用stopSelf(msg.arg1)這個方法來結束指定的工作。
注意下:回調完成後回調用 stopSelf(msg.arg1),注意這個msg.arg1是個int值,相當於一個請求的唯一標識。每發送一個請求,會生成一個唯一的標識,然後將請求放入隊列,當全部執行完成(最後一個請求也就相當於getLastStartId == startId),或者當前發送的標識是最近發出的那一個(getLastStartId == startId),則會銷毀我們的Service.如果傳入的是-1則直接銷毀。
當所有的工作執行完後:就會執行onDestroy方法。
@Override
public void onDestroy() {
mServiceLooper.quit();
}
服務結束後調用這個方法 mServiceLooper.quit()使looper停下來。
1、 IntentService是一個基於消息的服務,每次啟動該服務並不是馬上處理你的工作,而是首先會創建對應的Looper,Handler並且在MessageQueue中添 加的附帶客戶Intent的Message對象, 當Looper發現有Message的時候接著得到Intent對象通過在 onHandleIntent((Intent)msg.obj)中調用你的處理程序. 處理完後即會停止自己的服務. 意思是Intent的生命周期跟你的 處理的任務是一致的. 所以這個類用下載任務中非常好,下載任務結束後服務自身就會結束退出。
2、IntentService是不適合用於bindService()這樣的啟動方式的。其次我們通過startService多次啟動Service時,相當於在MessageQueue中添加了多個任務,就可以實現多任務按照順序執行。
3、只有在onHandleIntent()方法中執行的代碼才是在工作線程中運行的。IntentService的停止不是因為在handleMessage() 中執行了stopSelf(msg.arg1);而是系統自己停止的。
IOS中關於去掉標題只需類似下面的兩行代碼[js appendString:@var title = document.getElementsByClassName(
從1月份Google發布的16個關於性能優化的系列視頻起,這段時間在各大社區都有看到很多優秀的關於優化系列的文章。有分析了性能產生的原因、有分享如何優化我們的應用、有介紹
基礎知識度量聲音強度,大家最熟悉的單位就是分貝(decibel,縮寫為dB)。這是一個無綱量的相對單位,計算公式如下:分子是測量值的聲壓,分母是參考值的聲壓(20微帕,人
前言:github對開發者而言無疑是個寶藏,但想利用它可不是件簡單的事,用Android studio導入開源項目會遇到各種問題,今天我就以github上的一個圖片輪播項