Service生命周期:
啟動模式:
1.Start方式:
啟動后在后臺單獨執(zhí)行邑雅,不給組件返回結(jié)果
調(diào)用onstartCommand,需要調(diào)用stopService才能停止service
2.Bind方式:
可與綁定的組件進行交互
Service可與多個組件綁定妈经,不再與任何綁定才會destroy.
Service不是新的線程淮野,也不是新的進程
-
若您需要在Service中執(zhí)行較為耗時的操作(如播放音樂、執(zhí)行網(wǎng)絡(luò)請求等)吹泡,需要在Service中創(chuàng)建一個新的線程Thread還是使用Service?
看是否需要與用戶交互骤星,要交互用thread,不交互可用service爆哑。
IntentService默認(rèn)啟動子線程洞难,操作完成后無需調(diào)用stop,onHandleIntent()會自動調(diào)用該方法
啟動service:
Intent intent = new Intent(this,MyIntentService.class);
與activity啟動方式類似,startService(intent);前臺service:
前臺Service用于動態(tài)通知消息揭朝,如天氣預(yù)報队贱。該Service不易被kill。
一個播放音樂的Service必須是前臺Service萝勤,只有這樣用戶才能確知其運行狀態(tài)-
service調(diào)用的各種方法:
-
service連接回調(diào):
Service啟動方式
1.Service的第一種啟動方式露筒,采用start的方式開啟服務(wù)
1.定義一個類繼承Service
2.在Manifest.xml文件中配置該Service
3.使用Context的startService(Intent)方法啟動該Service
4.不再使用時,調(diào)用stopService(Intent)方法停止該服務(wù)
使用這種start方式啟動的Service的生命周期如下:
onCreate()--->onStartCommand() ---> onDestory()
特點:一旦服務(wù)開啟跟調(diào)用者(開啟者)就沒有任何關(guān)系了敌卓。
開啟者退出了慎式,開啟者掛了,服務(wù)還在后臺長期的運行趟径。
開啟者不能調(diào)用服務(wù)里面的方法瘪吏。
2.Service的第二種啟動方式,采用bind的方式開啟服務(wù)
1.定義一個類繼承Service
2.在Manifest.xml文件中配置該Service
3.使用Context的bindService(Intent, ServiceConnection, int)方法啟動該Service
4.不再使用時蜗巧,調(diào)用unbindService(ServiceConnection)方法停止該服務(wù)
使用這種start方式啟動的Service的生命周期如下:
onCreate() --->onBind()--->onunbind()--->onDestory()
特點:bind的方式開啟服務(wù)掌眠,綁定服務(wù),調(diào)用者掛了幕屹,服務(wù)也會跟著掛掉蓝丙。
綁定者可以調(diào)用服務(wù)里面的方法级遭。
啟動過程代碼:
public class MainActivity extends Activity {
private MyConn conn;
private Intent intent;
private IMyBinder myBinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//開啟服務(wù)按鈕的點擊事件
public void start(View view) {
intent = new Intent(this, MyService.class);
conn = new MyConn();
//綁定服務(wù),
// 第一個參數(shù)是intent對象渺尘,表面開啟的服務(wù)挫鸽。
// 第二個參數(shù)是綁定服務(wù)的監(jiān)聽器
// 第三個參數(shù)一般為BIND_AUTO_CREATE常量,表示自動創(chuàng)建bind
bindService(intent, conn, BIND_AUTO_CREATE);
}
//調(diào)用服務(wù)方法按鈕的點擊事件
public void invoke(View view) {
myBinder.invokeMethodInMyService();
}
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//iBinder為服務(wù)里面onBind()方法返回的對象鸥跟,所以可以強轉(zhuǎn)為IMyBinder類型
myBinder = (IMyBinder) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
}
關(guān)于Service其它問題
-
IntentService與Service的區(qū)別
Service做耗時操作容易引起ANR丢郊,所以創(chuàng)造一個IntentService是處理異步請求的一個類,在IntentService內(nèi)有一個工作線程來處理耗時操作医咨,啟動IntentService的方式和啟動傳統(tǒng)的Service一樣枫匾,同時,當(dāng)任務(wù)執(zhí)行完后拟淮,IntentService會自動停止干茉,而不需要我們手動去控制或stopSelf()。
-
Service怎么保證在后臺不被殺死惩歉?
重寫onStartCommand()方法等脂,將flags設(shè)置START_STICKY,服務(wù)被殺死之后系統(tǒng)會重新創(chuàng)建服務(wù)撑蚌。
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
flags = START_STICKY;
return super.onStartCommand(intent, flags, startId);
}
-
如何在service中彈出對話框
Service中可以彈出對話框。比如當(dāng)監(jiān)聽到電量變化搏屑,監(jiān)聽到接收短信争涌,用Service監(jiān)聽,然后在Service中彈出對話框辣恋。
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setMessage("有新消息亮垫,是否查看?");
alertDialog.setPositiveButton("否",
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
}
});
alertDialog.setNegativeButton("是",
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
}
});
ad = alertDialog.create();
ad.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
ad.setCanceledOnTouchOutside(false);//點擊外面區(qū)域不會讓dialog消失
ad.show();
關(guān)鍵點是要給dialog添加setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)伟骨,類型是系統(tǒng)彈框饮潦。并加入系統(tǒng)彈框的權(quán)限。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />