轉載請標明出處:http://blog.csdn.net/donkor_/article/details/78875391
前言:
ServiceTimeout(20 seconds)小概率類型Service在特定的時間內無法處理完成,會造成ANR — 應用程序無響應(ANR:Application Not Responding)的情況
▲ 分析 :
避免ANR最核心的一點就是在主線程減少耗時操作。這時我們建議使用intentService處理。intentService是一個異步的,會自動停止的服務,很好解決了傳統的Service中處理完耗時操作忘記停止並銷燬Service的問題
▲ 區別 :
1. 首先IntentService是繼承自Service;
2. Service不是一個單獨的進程,它和應用程序在同一個進程中;
3. Service也不是一個線程,所以我們要避免在Service中進行耗時的操作;
4. IntentService使用隊列的方式將請求的Intent加入隊列,然後開啓了一個Worker Thread(工作線程)在處理隊列中的Intent,對於異步的startService請求,
IntentService會處理完成一個之後在處理第二個,每一個請求都會在一個單獨的Worker Thread中處理,不會阻塞應用程序的主線程。
因此,如果我們如果要在Service裏面處理一個耗時的操作,我們可以用IntentService來代替使用。
5. 使用IntentService 必須首先繼承IntentService並實現onHandleIntent()方法,將耗時的任務放在這個方法執行,其他方面,IntentService和Service一樣。
▲ 例子 :
Service_demo
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
//經測試,Service裏面是不能進行耗時的操作的,必須要手動開啓一個工作線程來處理耗時操作
Log.e("MyService","onStart");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("MyService","睡眠結束");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
IntentService_demo
public class MyIntentService extends IntentService {
public MyIntentService() {
super("donkor");
}
@Override
protected void onHandleIntent(Intent intent) {
// 經測試,IntentService裏面是可以進行耗時的操作的
//IntentService使用隊列的方式將請求的Intent加入隊列,然後開啓一個worker thread(線程)來處理隊列中的Intent
//對於異步的startService請求,IntentService會處理完成一個之後再處理第二個
Log.e("MyIntentService","onStart");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("MyIntentService","睡眠結束");
}
}
TextServiceActivity
public class TextServiceActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this,MyService.class));//主界面阻塞,最終會出現Application not responding
//連續兩次啓動IntentService,會發現應用程序不會阻塞,而且最重的是第二次的請求會再第一個請求結束之後運行(這個證實了IntentService採用單獨的線程每次只從隊列中拿出一個請求進行處理)
startService(new Intent(this,MyIntentService.class));
startService(new Intent(this,MyIntentService.class));
}
}
About me
Email :[email protected]
Android開發交流QQ羣 : 537891203