如何给Android应用创建本地服务
Android系統給應用提供了兩種類型的服務:啟動型本地服務和綁定型本地服務,這兩種服務的詳細信息請參考“Android Service開發指南”
Android Service開發指南原文網址如下:
http://developer.android.com/guide/topics/fundamentals/services.html
http://developer.android.com/guide/topics/fundamentals/bound-services.html
本文通過代碼向大家詳細介紹和演示這兩種的服務的創建過程,代碼適用于Android2.3.3以后的版本。
1.?定義清單文件(AndroidManifest.xml)
<?xml version="1.0" encoding="utf-8"?>
<!-- 本例為了方便,將啟動類型服務的Activity和綁定類型服務的Activity放到了一個類中:
???? LocalServiceActivities.java -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
????? package="my.android.test"
????? android:versionCode="1"
????? android:versionName="1.0">
??? <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="9"/>
??? <application android:icon="@drawable/icon" android:label="@string/app_name">
??????? <!-- 本地服務LocalService -->
??????? <service android:name="LocalService" />
??????? <!-- 啟動類型服務的Activity,內部類Controller-->
??????? <activity android:name=".LocalServiceActivities$Controller"
????????????????? android:label="@string/app_name"
????????????????? android:launchMode="singleTop">
??????????? <intent-filter>
??????????????? <action android:name="android.intent.action.MAIN" />
??????????????? <category android:name="android.intent.category.LAUNCHER" />
??????????? </intent-filter>
??????? </activity>
???????? <!-- 綁定類型服務的Activity,要運行本服務,需要將下面的注釋去掉,
??????????????????????????????????? 同時給上面的啟動類型服務的Activity給注釋掉 -->
???????? <!--
??????? <activity android:name=".LocalServiceActivities$Binding"
????????????????? android:label="@string/app_name"
????????????????? android:launchMode="singleTop">
??????????? <intent-filter>
??????????????? <action android:name="android.intent.action.MAIN" />
??????????????? <category android:name="android.intent.category.LAUNCHER" />
??????????? </intent-filter>
??????? </activity>
????????? -->
??? </application>
</manifest>
2.?定義字符資源(strings.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
??? <string name="hello">Hello World, LocalServiceActivity!</string>
??? <string name="app_name">LocalServiceApp</string>
??? <string name="activity_local_service_controller">App/Service/Local Service Controller</string>
??? <string name="local_service_controller">This demonstrates how you can implement persistent services that
??????? may be started and stopped as desired.</string>
??? <string name="start_service">Start Service</string>
??? <string name="stop_service">Stop Service</string>
???
??? <string name="local_service_started">Local service has started</string>
??? <string name="local_service_stopped">Local service has stopped</string>
??? <string name="local_service_label">Sample Local Service</string>
???
??? <string name="activity_local_service_binding">App/Service/Local Service Binding</string>
??? <string name="local_service_binding">This demonstrates how you can connect with a persistent
??????? service.? Notice how it automatically starts for you, and play around with the
??????? interaction between this and Local Service Controller.</string>
??? <string name="bind_service">Bind Service</string>
??? <string name="unbind_service">Unbind Service</string>
??? <string name="local_service_connected">Connected to local service</string>
??? <string name="local_service_disconnected">Disconnected from local service</string>
</resources>
3.?定義布局資源
3.1. local_service_controller.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
??? android:gravity="center_horizontal"
??? android:layout_width="match_parent" android:layout_height="match_parent">
??? <TextView
??????? android:layout_width="match_parent" android:layout_height="wrap_content"
??????? android:layout_weight="0"
??????? android:paddingBottom="4dip"
??????? android:text="@string/local_service_controller"/>
??? <Button android:id="@+id/start"
??????? android:layout_width="wrap_content" android:layout_height="wrap_content"
??????? android:text="@string/start_service">
??????? <requestFocus />
??? </Button>
??? <Button android:id="@+id/stop"
??????? android:layout_width="wrap_content" android:layout_height="wrap_content"
??????? android:text="@string/stop_service">
??? </Button>
</LinearLayout>
3.2. local_service.binding.xml
??? <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
??? android:gravity="center_horizontal"
??? android:layout_width="match_parent" android:layout_height="match_parent">
??? <TextView
??????? android:layout_width="match_parent" android:layout_height="wrap_content"
??????? android:layout_weight="0"
??????? android:paddingBottom="4dip"
??????? android:text="@string/local_service_binding"/>
??? <Button android:id="@+id/bind"
??????? android:layout_width="wrap_content" android:layout_height="wrap_content"
??????? android:text="@string/bind_service">
??????? <requestFocus />
??? </Button>
??? <Button android:id="@+id/unbind"
??????? android:layout_width="wrap_content" android:layout_height="wrap_content"
??????? android:text="@string/unbind_service">
??? </Button>
</LinearLayout>
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();
?????? }
??? }
}
?
轉載于:https://www.cnblogs.com/phonegap/archive/2012/04/28/2535826.html
總結
以上是生活随笔為你收集整理的如何给Android应用创建本地服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vim中文对齐
- 下一篇: [Innost]Android深入浅出之