Service
Android開發(fā)者文檔里這樣定義:
A service is a component that runs in the background to perform long-running operations or to perform work for remote processes. A service does not provide a user interface. For example, a service might play music in the background while the user is in a different app, or it might fetch data over the network without blocking user interaction with an activity.Another component, such as an activity, can start the service and let it run or bind to it in order to interact with it.
Service是Android提供的四大組件之一,我們可以認為它是一個沒有用戶界面、開發(fā)者創(chuàng)建的組件,它可以用來執(zhí)行長久的操作,可以超出單個Activity的范圍。Service可以作為客戶端/服務(wù)器開發(fā)模式的服務(wù)器,通過進程間通信(IPC)提供遠程調(diào)用服務(wù)。
如果一個任務(wù)需要使用worker線程,可能會影響應(yīng)用的響應(yīng)速度和性能,而這個任務(wù)對處理時間并不敏感,那就考慮使用Service,在主要應(yīng)用程序和任何單獨的Activity生命周期外處理任務(wù)。
常見應(yīng)用
- 天氣、電子郵件或者社交網(wǎng)絡(luò)的App,可以定期檢查網(wǎng)絡(luò)上更新的服務(wù)。
- 一個游戲,可以在用戶需要的時候創(chuàng)建一個Service下載并處理相關(guān)內(nèi)容。
- 一個照片或者多媒體應(yīng)用保持數(shù)據(jù)的在線同步。
- 一個視頻編輯軟件,可以將繁重的處理工作放置在服務(wù)隊列,降低系統(tǒng)能耗。
- 一個新聞應(yīng)用,可以實現(xiàn)預(yù)加載內(nèi)容的服務(wù),當用戶啟動時,提前下載相應(yīng)新聞,提高性能和相應(yīng)能力。
開啟Service的兩種方式:
- startService(Intent serviceIntent) 一個組件可以通過startService的方式來開啟Service服務(wù)。這種方式開啟的Service可以調(diào)用stopSelf()來停止服務(wù),也可以通過在其他組件中調(diào)用stopService()方法來停止。
Intent serviceIntent = new Intent(this, FirstStartedService.class);
startService(serviceIntent);
FirstStartedService就是開啟的繼承自Service的服務(wù)。
public class FirstStartedService extends Service {
private CustomHanlder ch;
public FirstStartedService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.w("service created:","flag");
HandlerThread ht=new HandlerThread("handler.thread.name");
ht.start();
ch=new CustomHanlder(ht.getLooper());
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.w("service started:","flag");
Log.w("main thread id:",""+Thread.currentThread().getName()+Thread.currentThread().getId());
//do service task;
//stopSelf();
ch.sendEmptyMessage(0);
return Service.START_STICKY;
}
private class CustomHanlder extends Handler{
public CustomHanlder(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
Log.w("handler thread id:",""+Thread.currentThread().getName()+Thread.currentThread().getId());
}
}
}
2.bindService(Intent service ,ServiceConnection conn ,Int flags) 參數(shù)service是指要綁定的Service,conn是ServiceConnection對象,這個對象不能為null,flags為binding的類型,可以為0。 這種方式開啟的Service會一直運行,直到?jīng)]有組件綁定這個Service的時候系統(tǒng)才會停止Service。一般情況下,一個組件在不需要Service服務(wù)后要調(diào)用unBindService(ServiceConnection conn)來解綁Service。
一個簡單示例:Activity作為客戶端使用bindService的方式開啟一個Service服務(wù),并向服務(wù)端發(fā)送一個字符串,服務(wù)端接收字符串后向客戶端返回一個字符串。這也是一個簡單的進程間通信(IPC)的例子
客戶端代碼:
public class ServiceTestScreen extends AppCompatActivity {
private TextView tv;
public ServiceTestScreen() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_test_screen);
tv = (TextView) findViewById(R.id.reply_text);
}
public void onClickButton(View v) {
int id = v.getId();
switch (id) {
case R.id.start_service: {
Intent serviceIntent = new Intent(this, FirstStartedService.class);
startService(serviceIntent);
break;
}
case R.id.bind_service: {
Intent serviceIntent = new Intent(this, FirstBinderService.class);
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
break;
}
case R.id.start_intent_service: {
Intent serviceIntent = new Intent(this, FirstIntentService.class);
startService(serviceIntent);
break;
}
case R.id.send_msg: {
if (serviceBound) {
if (serverMsger != null) {
Message msg = new Message();
Bundle data = new Bundle();
data.putString("send", "client msg");
msg.setData(data);
msg.replyTo = clientMsger;
try {
serverMsger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
break;
}
}
}
private boolean serviceBound = false;
private Messenger serverMsger;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.w("component name:", name.getClassName());
serverMsger = new Messenger(binder);
serviceBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
serverMsger = null;
serviceBound = false;
}
};
private Handler h = new Handler() {
@Override
public void handleMessage(Message msg) {
tv.setText(msg.getData().getString("reply"));
}
};
private Messenger clientMsger = new Messenger(h);
@Override
protected void onStop() {
super.onStop();
if (serviceBound) {
unbindService(serviceConnection);
serviceBound = false;
serverMsger = null;
}
}
}
服務(wù)端代碼:
public class FirstBinderService extends Service {
private final Messenger serverMsger = new Messenger(new MessageHandler());
public FirstBinderService() {
}
@Override
public IBinder onBind(Intent intent) {
return serverMsger.getBinder();
}
private class MessageHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Message replyMsg = new Message();
Bundle data = new Bundle();
data.putString("reply", msg.getData().getString("send") + "--server msg");
replyMsg.setData(data);
try {
msg.replyTo.send(replyMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
示例效果圖:

總結(jié)
本文主要總結(jié)了Android中啟動Service的兩種方式,并用了具體示例來進行演示,完成了使用bindService的方式進行進程間通信。如果總結(jié)的有錯誤或不足的地方,歡迎大家批評指正。
示例代碼
個人主頁
GitHub