2)和Activity交互的本地服務(wù)
剛剛我們介紹的Service是不需要與Activity進(jìn)行交互的,現(xiàn)在我們?cè)賮?lái)看看與Activity交互的本地服務(wù)。首先,我們新建1個(gè)BindLocalServide類繼承自Serivce,代碼以下:
// import略 public class BindLocalServideextends Service {
private static final String TAG = "localservice"; private MyBinder myBinder = new MyBinder();
@Override public IBinder onBind(Intent intent) { return myBinder; } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); }
public class MyBinder extends Binder{ public LocalService getService(){ return LocalService.this; } } } |
然后,我們新建1個(gè)BindServiceActivity類繼承自Actvity,代碼以下:
// import略 public class BindServiceActivity extends Activity{
private Button startBtn,stopBtn; private boolean flag;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.localservice); startBtn = (Button)findViewById(R.id.start_button); stopBtn = (Button)findViewById(R.id.stop_button); startBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(BindServiceActivity.this,LocalService.class); bindService(intent, conn, Context.BIND_AUTO_CREATE); } }); stopBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(flag == true){ unbindService(conn); flag = false; } } }); } private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) {
}
@Override public void onServiceConnected(ComponentName name, IBinder service) { MyBinder binder = (MyBinder)service; LocalService bindService = binder.getService(); bindService.MyMethod(); flag = true; } }; } |
在這里,也是使用之前使用過(guò)的localservice.xml布局文件,定義了“啟動(dòng)”和“停止”兩個(gè)按鈕。另外,別忘了在AndroidMainfest.xml中注冊(cè)Service:
<service android:name=". BindLocalServideextends "/> |
這里可以發(fā)現(xiàn)onBind需要返回1個(gè)IBinder對(duì)象。也就是說(shuō)和上1例子LocalService不同的是:
1)添加了1個(gè)public內(nèi)部類繼承Binder,并添加getService方法來(lái)返回當(dāng)前的Service對(duì)象;
2)新建1個(gè)IBinder對(duì)象――new那個(gè)Binder內(nèi)部類;
3)onBind方法返還那個(gè)IBinder對(duì)象。
然后,我們來(lái)看看打印出來(lái)的效果,如圖4⑻所示:
圖4⑻ onBind Service履行順序
通過(guò)日志,我們可以發(fā)現(xiàn),通過(guò)bindService這類方法啟動(dòng)服務(wù),當(dāng)服務(wù)啟動(dòng)后,屢次啟動(dòng)只有第1次有效,并且與服務(wù)相綁定的Activity“死亡”時(shí),該服務(wù)也停止。
我們?cè)谑褂媚承〢ndroid利用的時(shí)候,可能會(huì)發(fā)現(xiàn)安裝了某個(gè)利用以后,會(huì)有1些服務(wù)也會(huì)隨之運(yùn)行。而且,有的服務(wù)每次都會(huì)隨著手機(jī)開機(jī)而自動(dòng)啟動(dòng)。下面,就讓我們1起來(lái)看看是怎樣樣實(shí)現(xiàn)開機(jī)自啟動(dòng)服務(wù)的。
首先,我們需要來(lái)了解1下Android中的 BroadcastReceiver:
BroadcastReceiver也就是“廣播接收者”的意思,顧名思義,它就是用來(lái)接收來(lái)自系統(tǒng)和利用中的廣播。
在Android系統(tǒng)中,廣播利用在各個(gè)方面。例如當(dāng)開機(jī)完成后系統(tǒng)會(huì)產(chǎn)生1條廣播,接收到這條廣播就可以實(shí)現(xiàn)開機(jī)啟動(dòng)服務(wù)的功能;當(dāng)網(wǎng)絡(luò)狀態(tài)改變時(shí)系統(tǒng)會(huì)產(chǎn)生1條廣播,接收到這條廣播就可以及時(shí)地做出提示和保存數(shù)據(jù)等操作;當(dāng)電池電量改變時(shí),系統(tǒng)會(huì)產(chǎn)生1條廣播,接收到這條廣播就可以在電量低時(shí)告知用戶及時(shí)保存進(jìn)度,等等。
正是基于這樣的原理,只要實(shí)現(xiàn)1個(gè)BroadcastReceiver,我們就能夠監(jiān)聽開機(jī)時(shí)候的廣播(手機(jī)啟動(dòng)完成的事件ACTION_BOOT_COMPLETED),當(dāng)收到開機(jī)“信號(hào)”時(shí),啟動(dòng)相應(yīng)的服務(wù)。
我們用1個(gè)簡(jiǎn)單的例子來(lái)看看它是如何實(shí)現(xiàn)的。
首先,我們新建1個(gè)MyReceiver類繼承自BroadcastReceiver,代碼以下:
// import略 public class MyReceiver extends BroadcastReceiver {
private static final String POWERN_ON_ACTION = "android.intent.action.BOOT_COMPLETED";
public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(POWERN_ON_ACTION)) { startService(new Intent("com.char4.LOCAL_SERVICE")); } } } |
我們要讓這個(gè)Receiver工作,需要把它注冊(cè)到Android系統(tǒng)上,去監(jiān)聽廣播的BOOT_COMPLETED intent。在AndroidManifest.xml中添加以下代碼:
<receiver android:name=".MyReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> |
這樣重新開機(jī)以后,服務(wù)就會(huì)在系統(tǒng)啟動(dòng)終了后自動(dòng)運(yùn)行了。