如何给Android应用创建本地服务

来源:互联网 发布:大数据主要来源于人 编辑:程序博客网 时间:2024/05/29 15:19

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

<?xmlversion="1.0"encoding="utf-8"?>

<!-- 本例为了方便,将启动类型服务的Activity和绑定类型服务的Activity放到了一个类中:

     LocalServiceActivities.java -->

<manifestxmlns: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>

               <actionandroid:name="android.intent.action.MAIN"/>

               <categoryandroid: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

<?xmlversion="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

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns: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"?>

<LinearLayoutxmlns: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 Controllerextends 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 OnClickListenermStartListener =new OnClickListener(){

          publicvoid onClick(View v){

             //启动LocalService服务。

             startService(new Intent(Controller.this, LocalService.class));

          }

       };

       /**

        * stop按钮的点击事件监听器实现。

        */

       private OnClickListenermStopListener =new OnClickListener(){

          publicvoid onClick(View v){

             //终止LocalService服务。

             stopService(new Intent(Controller.this, LocalService.class));

          }

       };

    }

   

    /***************************************************************

     *以下是绑定型服务客户端的实现

     ***************************************************************/

   

    /**

     * Binding类是绑定类型服务的客户端,它包含两个按钮:

     * bind:点击该按钮时,调用bindService()方法绑定并启动服务;

     * unbind:点击该按钮时,调用unbindService()方法解除绑定并终止服务。

     */

    publicstaticclass Bindingextends Activity{

       //用于保存服务的绑定状态,true:绑定,false:未绑定

       privatebooleanmIsBound;

       //用于保存被绑定的本地服务实例。

       private LocalServicemBoundService;

       /**

        * 实现监视被绑定服务状态的接口:ServiceConnection

        * 绑定类型服务都要实现这个接口,以便监视服务的状态,这个接口中的方法会在

        * 应用的主线程中被调用。

        */

       private ServiceConnectionmConnection =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 OnClickListenermBindListener =new OnClickListener(){

          publicvoid onClick(View v){

             //绑定并启动服务。

             doBindService();

          }

       };

       /**

        * unbind按钮的点击事件监听器接口实现。

        */

       private OnClickListenermUnbindListener =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基础AndroidService类,实现应用的本地服务组件。

 *该服务使用HandlerThread类创建了服务自己的线程和消息循环,

 *因此,不会因为服务中的长时处理,而阻塞界面的刷新,影响用户体验。

 */

publicclass LocalServiceextends Service {

    //用于保存本服务自己的消息循环对象Looper

    private LoopermServiceLooper;

    //用于保存内部类ServiceHandler的对象实例,它继承了AndroidHandler,

    //用于处理发送给服务的消息。

    private ServiceHandlermServiceHandler;

   

    /**

     * 这个类用于给客户端提供绑定对象,因为本示例的服务与客户端运行在同一个

     * 主进程中,所以不需要处理进程间通信(IPC

     */

    publicclass LocalBinderextends 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:有关启动请求的附加数据,可以是:0START_FLAG_REDELIVERYSTART_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 IBindermBinder = new LocalBinder();

    /**

     * 该类继承AndroidHandler类,为线程的消息循环提供发送和处理消息的功能,

     * 本示例覆写了handleMessage()方法,用来处理发送给服务消息循环的消息。

     */

    privatefinalclass ServiceHandlerextends 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();

       }

    }

}

 

原创粉丝点击