androidlocal
❶ 如何給Android應用創建本地服務
本文通過代碼向大家詳細介紹和演示這兩種的服務的創建過程,代碼適用於Android2.3.3以後的版本。
1. 定義清單文件(AndroidManifest.xml)
4. 創建服務啟動界面(LocalServiceActivities.java)
package my.android.test;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
/**
* 該類中包含兩種類型服務的客戶端:
* 啟動類型服務客戶端:Controller
* 綁定類型服務客戶端:Binding
*/
publicclass LocalServiceActivities {
/**
* Controller類是啟動類型服務的客戶端,它包含兩個按鈕:
* start:點擊該按鈕時,啟動服務。
* stop: 點擊該按鈕時,終止服務。
*/
publicstaticclass Controller extends Activity{
/**
* Activity被首次啟動時,調用該方法。
*/
@Override
protectedvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//填充布局
setContentView(R.layout.local_service_controller);
//查找布局中的啟動服務按鈕,並設置點擊事件監聽器。
Button button = (Button)findViewById(R.id.start);
button.setOnClickListener(mStartListener);
//查找布局中的終止服務按鈕,並設置點擊事件監聽器。
button = (Button)findViewById(R.id.stop);
button.setOnClickListener(mStopListener);
}
/**
* start按鈕的點擊事件監聽器實現。
*/
private OnClickListener mStartListener = new OnClickListener(){
publicvoid onClick(View v){
//啟動LocalService服務。
startService(new Intent(Controller.this, LocalService.class));
}
};
/**
* stop按鈕的點擊事件監聽器實現。
*/
private OnClickListener mStopListener = new OnClickListener(){
publicvoid onClick(View v){
//終止LocalService服務。
stopService(new Intent(Controller.this, LocalService.class));
}
};
}
/***************************************************************
*以下是綁定型服務客戶端的實現
***************************************************************/
/**
* Binding類是綁定類型服務的客戶端,它包含兩個按鈕:
* bind:點擊該按鈕時,調用bindService()方法綁定並啟動服務;
* unbind:點擊該按鈕時,調用unbindService()方法解除綁定並終止服務。
*/
publicstaticclass Binding extends Activity{
//用於保存服務的綁定狀態,true:綁定,false:未綁定
privatebooleanmIsBound;
//用於保存被綁定的本地服務實例。
private LocalService mBoundService;
/**
* 實現監視被綁定服務狀態的介面:ServiceConnection
* 綁定類型服務都要實現這個介面,以便監視服務的狀態,這個介面中的方法會在
* 應用的主線程中被調用。
*/
private ServiceConnection mConnection = new ServiceConnection(){
/**
* 當連接的服務被創建時,Android系統會調用這個方法,用IBinder對象跟服務建立通信通道。
* @param className:被連接的具體的服務組件的名稱
* @param service:服務的通信通道IBinder對象。
*/
publicvoid onServiceConnected(ComponentName className, IBinder service){
//從IBinder對象中獲取服務實例。
mBoundService = ((LocalService.LocalBinder)service).getService();
//顯示Activity已經與服務建立了連接的提示消息。
Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show();
}
/**
* 當服務被終止時,Android系統會調用這個方法。
*/
publicvoid onServiceDisconnected(ComponentName className){
//清除客戶端服務實例
mBoundService = null;
//顯示服務被終止的提示消息。
Toast.makeText(Binding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show();
}
};
/**
* 綁定並啟動服務,bind按鈕點擊時會調用這個方法。
*/
void doBindService(){
//綁定並啟動服務。
bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
/**
* 解除與服務的綁定,unbind按鈕被點擊時會調用這個方法
*/
void doUnbindService(){
//如果服務被綁定,則解除與服務綁定。
if(mIsBound){
unbindService(mConnection);
mIsBound = false;
}
}
/**
* 當Activity被銷毀時,調用解除綁定服務的方法,解除被綁定的服務。
*/
@Override
protectedvoid onDestroy(){
super.onDestroy();
//解除被綁定的服務。
doUnbindService();
}
/**
* bind按鈕的點擊事件監聽器介面實現。
*/
private OnClickListener mBindListener = new OnClickListener(){
publicvoid onClick(View v){
//綁定並啟動服務。
doBindService();
}
};
/**
* unbind按鈕的點擊事件監聽器介面實現。
*/
private OnClickListener mUnbindListener = new OnClickListener(){
publicvoid onClick(View v){
//解除被綁定的服務。
doUnbindService();
}
};
/**
* Activity被首次啟動時,會調用這個方法。
*/
@Override
protectedvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//填充Activity
setContentView(R.layout.local_service_binding);
//查找布局中的bind按鈕,並設置點擊事件的監聽器
Button button = (Button)findViewById(R.id.bind);
button.setOnClickListener(mBindListener);
//查找布局中的unbind按鈕,並設置點擊事件的監聽器
button = (Button)findViewById(R.id.unbind);
button.setOnClickListener(mUnbindListener);
}
}
}
5. 創建服務(LocalService.java)
package my.android.test;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;
import android.widget.Toast;
/**
* LocalService基礎Android的Service類,實現應用的本地服務組件。
* 該服務使用HandlerThread類創建了服務自己的線程和消息循環,
* 因此,不會因為服務中的長時處理,而阻塞界面的刷新,影響用戶體驗。
*/
publicclass LocalService extends Service {
//用於保存本服務自己的消息循環對象Looper
private Looper mServiceLooper;
//用於保存內部類ServiceHandler的對象實例,它繼承了Android的Handler類,
//用於處理發送給服務的消息。
private ServiceHandler mServiceHandler;
/**
* 這個類用於給客戶端提供綁定對象,因為本示例的服務與客戶端運行在同一個
* 主進程中,所以不需要處理進程間通信(IPC)
*/
publicclass LocalBinder extends Binder{
LocalService getService(){
//返回本服務的實例。
return LocalService.this;
}
}
/**
* 服務被首次創建時,系統調用這個方法。
* Android服務組件必須覆寫這個方法
*/
@Override
publicvoid onCreate(){
//創建線程對象,並啟動線程。
HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
//獲取線程的消息循環對象
mServiceLooper = thread.getLooper();
//用線程的消息循環對象創建消息處理對象。
mServiceHandler = new ServiceHandler(mServiceLooper);
}
/**
* 啟動類型服務必須實現這個方法,客戶端每次調用startService()方法時,
* 系統都會調用這個方法。
* @param intent:它是傳遞給startService()方法的Intent對象。
* @param flags:有關啟動請求的附加數據,可以是:0、START_FLAG_REDELIVERY或START_FLAG_RETRY.
* @param startId:一個唯一的整數,代表一次具體的請求,用於stopSelfResult(int)方法。
*/
@Override
publicint onStartCommand(Intent intent, int flags, int startId){
Log.i("LocalService", "Received star id" + startId + ":" + intent);
//顯示服務啟動的提示信息
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
//獲取要傳遞給服務消息循環的Message對象。
Message msg = mServiceHandler.obtainMessage();
//初始化Message對象的成員變數。
msg.arg1 = startId;
msg.obj = "Message processing......" + startId;
//把消息發送給服務線程的消息循環。
mServiceHandler.sendMessage(msg);
returnSTART_STICKY;
}
/**
* 必須覆寫這個方法,服務被終止時要調用這個方法,清理服務所佔用的資源。
*/
@Override
publicvoid onDestroy(){
//退出服務線程的消息循環。
mServiceLooper.quit();
//顯示服務被退出的提示信息。
Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
}
/**
* 綁定型服務必須覆寫這個方法,啟動型服務也可覆寫這個方法,只要返回null即可。
*/
@Override
public IBinder onBind(Intent intent){
//返回本服務對象實例。
returnmBinder;
}
privatefinal IBinder mBinder = new LocalBinder();
/**
* 該類繼承Android的Handler類,為線程的消息循環提供發送和處理消息的功能,
* 本示例覆寫了handleMessage()方法,用來處理發送給服務消息循環的消息。
*/
privatefinalclass ServiceHandler extends Handler{
//類實例化時,需要傳入服務線程的消息循環對象
public ServiceHandler(Looper looper){
super(looper);
}
/**
* 覆寫Handler類的handleMessage()方法,當服務線程的消息循環接收到外部
* 發送的消息時,會調用這個方法來處理對應的消息,本示例只是簡單的向用戶提示消息被處理的信息。
*/
@Override
publicvoid handleMessage(Message msg){
long endTime = System.currentTimeMillis() + 5 * 1000;
while (System.currentTimeMillis() < endTime){
synchronized(this){
try{
wait(endTime - System.currentTimeMillis());
CharSequence cs = msg.obj.toString();
Toast.makeText(LocalService.this, cs, Toast.LENGTH_SHORT).show();
//showNotification();
}catch(Exception e){
//
}
}
}
//消息被處理之後,終止本服務。
LocalService.this.stopSelf();
}
}
}