Service基本操作方法

来源:互联网 发布:js 获取android版本号 编辑:程序博客网 时间:2024/06/14 06:59

Service基本操作方法

一、 声明service

<manifest ...>
  ...
  <application ... >
      <service android:name=".ExampleService"/>
      ...
  </application>
</manifest>

此处也可以添加intent-filter

 

二、 started service

2.1 组件activity开启service

            Intent intent = new Intent();

            intent.setClass(MainActivity.this,FirstService.class);

            startService(intent);


或者以action方式开启

           Intent intent = new Intent();

            //为Intent设置Action属性

            intent.setAction("org.crazyit.service.FIRST_SERVICE");

            startService(intent);


此时需在manifest中进行声明

<!-- 配置一个Service组件 -->

   <serviceandroid:name=".FirstService">

         <intent-filter>

              <!--为该Service组件的intent-filter配置action -->

              <actionandroid:name="org.crazyit.service.FIRST_SERVICE" />

        </intent-filter>

    </service>


后台FirstService响应activity

//当创建一个Servcie对象之后,会首先调用这个函数

//Called by the system when the service is first created.Do not call this method directly

        @Override

        public voidonCreate() {

               super.onCreate();

               System.out.println("ServiceonCreate");

        }

        //当activity startService()时调用这个函数,把intent对象传递进来

        @Override

        //startId会递增

        public intonStartCommand(Intent intent, int flags, int startId) {


               System.out.println("ServiceonStartCommand");

               return super.onStartCommand(intent,flags, startId);

        }


2.2停止service:1 组件activity停止  2 service自己停止

 2.2.1组件activity停止

class StopServiceListener implements OnClickListener {

       public voidonClick(View v) {

              Intentintent = new Intent();

              intent.setClass(MainActivity.this,FirstService.class);

              stopService(intent);

              }

       }



后台FirstService响应activity

//stopService时调用这个函数,做善后处理

        @Override

        public voidonDestroy() {

               System.out.println("ServiceonDestory");

               super.onDestroy();

        }


2.2.2 service自己停止

service类的代码中

stopSelf()

 


三、 Bound service

 3.1 自定义方法

1 bindService

button.setOnClickListener(new OnClickListener() {

           publicvoid onClick(View v) {

                  Intentintent = new Intent();

                  intent.setClass(MainActivity.this,SecondService.class);

//捆绑service,然后自动调用serviceonBind方法,onBind方法returnIBinder对象

//然后把service返还的数据放到ServiceConnection类型的对象coon

//coononServiceConnected方法中接受并处理数据

                  bindService(intent,conn, BIND_AUTO_CREATE);

                  }

});

//匿名内部类,作为对象赋值给coon

ServiceConnection conn = new ServiceConnection() {

                    @Override

                publicvoid onServiceDisconnected(ComponentName name) {

                }

                       @Override

                publicvoid onServiceConnected(ComponentName name, IBinder service) {

                       FirstBindbinder = (FirstBind)service;

                       Stringdata = binder.getData();

                    System.out.println("data--->"+data);

                }

};


2 service响应activity

public class SecondService extends Service {

//当其他应用程序(一般为activity)首次绑定至当前的service对象时,自动调用该方法

@Override

public IBinder onBind(Intent intent) {

//BinderIBinder的子类,则FirstBind也是其子类,父类引用指向子类对象

             IBinderibinder = new FirstBind();

             return ibinder;                   

             }

    classFirstBind extends Binder {

             publicString getData() {

             return"huxiaohuhunao";

             }

}

}


去除绑定

Activity

button1.setOnClickListener(new OnClickListener(){

           @Override

           publicvoid onClick(View v) {

                         unbindService(conn);

           }

});


Service响应

// Service被断开连接时回调该方法

         @Override

         publicboolean onUnbind(Intent intent)

           {

                    System.out.println("Serviceis Unbinded");

                               return true;

             }

// Service被关闭之前回调该方法。

    @Override

      publicvoid onDestroy()

      {

                  super.onDestroy();

           System.out.println("Serviceis Destroyed");

         }


3.2 使用transact,onTransact方法

绑定service

  button1.setOnClickListener(newOnClickListener() {

           @Override

           publicvoid onClick(View v) {

                  Intentintent = new Intent();

                  intent.setClass(MainActivity.this,SecondService.class);

             //捆绑service,然后自动调用serviceonBind方法,onBind方法returnIBinder对象

           //然后把service返还的数据放到ServiceConnection类型的对象coon

           //coononServiceConnected方法中接受并处理数据

           bindService(intent,conn, BIND_AUTO_CREATE);

           }

});

 

//匿名内部类,作为对象赋值给coon

ServiceConnection conn = new ServiceConnection()

         @Override

public void onServiceDisconnected(ComponentNamename)

      }

         @Override

         publicvoid onServiceConnected(ComponentName name, IBinder service) {

                  MainActivity.this.binder= (Binder)service

                  }

           };

 


service响应activity

public class SecondService extends Service{

    @Override

    publicIBinder onBind(Intent intent) {

           returnnew MyBinder();

    }

 

    classMyBinder extends Binder {

           @Override

protected boolean onTransact(int code, Parceldata, Parcel reply,

int flags) throws RemoteException {

                       System.out.println("code--->"+code);

                       Stringstr = data.readString();

                       System.out.println("service get:"+str);

                       reply.writeString("from service");

                        returnsuper.onTransact(code, data, reply, flags);

      }                         

}

}


Activity响应service

//activityservice互相传输数据

button2.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View v) {

/*一,先从序列说起

我们都知道JAVA中的Serialize机制,译成串行化、序列化,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。

二,机器人中的新的序列化机制

Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC(进程间通信)机制,必然要求使用性能更出色的对象传输方式。在这样的环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。*/

//datareply相当于是一个容器,把数据序列化存入容器,取出时再恢复数据

Parcel data = Parcel.obtain();

Parcel reply = Parcel.obtain();

data.writeString("from activity");

try {

//当执行该代码时,service会同时执行onTransact方法,将data传递给service

//clienttransact(交易,谈判)serviceontransact,二者同时进行

 

            binder.transact(0, data, reply, 0);

             //同时还能接受来自service的数据

             Strings = reply.readString();

                System.out.println("activity get:"+s);

} catch (RemoteException e) {

                  e.printStackTrace();

}

}

});

 

 

四、IntentService

IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。

总结:

1 IntentService是Service的子类

2 IntentService会创建单独的worker线程来处理所有的Intent请求

3 IntentService会创建单独的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程问题

4      当所有问题处理完后,IntentService会自动停止,无需调用stopSelf()

5      为service的onBind()方法实现了默认实现,该实现返回null

6      为service的onStartCommand()方法实现了默认实现,该实现将请求Intent添加到队列中去

故:IntentService实现service,无需重写onBind(),onStartCommand(),只需要重写onHandleIntent()即可

 

启动IntentService

public void startIntentService(View source)

                    {

                               //创建需要启动的IntentServiceIntent

                               Intentintent = new Intent(this, MyIntentService.class);

                               //启动IntentService

                               startService(intent);

                    }


IntentService响应activity

// IntentService会使用单独的线程来执行该方法的代码

     @Override

     protectedvoid onHandleIntent(Intent intent)

    {

            //该方法内可以执行任何耗时任务,比如下载文件等,此处只是让线程暂停20

             longendTime = System.currentTimeMillis() + 20 * 1000;

              System.out.println("onStart");

             while(System.currentTimeMillis() < endTime)

             {

                   synchronized(this)

                   {

                            try

                             {

                                   wait(endTime- System.currentTimeMillis());

                            }

                            catch(Exception e)

                            {

                             }

                      }

               }

              System.out.println("---耗时任务执行完成---");

   }

 


五、跨进程调用service AIDL service(疯狂讲义coding)

定义AIDL接口

interface ICat

{

                    StringgetColor();

                    doublegetWeight();

}


然后ADT工具会自动在gen/包 目录下生成一个ICat.Java接口,该接口中包含一个Stu内部类,该内部类实现了IBinder,ICat两个接口

public static abstract class Stub extendsandroid.os.Binder implements ICat


service将接口暴漏给客户端

public class AidlService extends Service

{

        privateCatBinder catBinder;

        Timertimer = new Timer();

        String[]colors = new String[]{

            "红色",

             "黄色",

             "黑色"

          };

         double[]weights = new double[]{

               2.3,

                 3.1,

              1.58

          };

       privateString color;

      privatedouble weight;

     //继承Stub,也就是实现额ICat接口,并实现了IBinder接口

      public class CatBinder extends Stub

      {

            @Override

            public StringgetColor() throws RemoteException

            {

                   return color;

            }

            @Override

           public doublegetWeight() throws RemoteException

           {

                return weight;

           }

   }

  @Override

  publicvoid onCreate()

     {

             super.onCreate();

           catBinder= new CatBinder();


           timer.schedule(newTimerTask()

            {

                     @Override

                      publicvoid run()

                     {

                             //随机地改变Service组件内colorweight属性的值。

                             int rand =(int)(Math.random() * 3);

                             color= colors[rand];

                             weight= weights[rand];

                            System.out.println("--------"+ rand);

                       }

                 }, 0 , 800);

  }

     @Override

     public IBinder onBind(Intent arg0)

        {

              /*返回catBinder对象

            *在绑定本地Service的情况下,该catBinder对象会直接

               *传给客户端的ServiceConnection对象

                 *onServiceConnected方法的第二个参数;

                *在绑定远程Service的情况下,只将catBinder对象的代理

              *传给客户端的ServiceConnection对象

                *onServiceConnected方法的第二个参数;

                   */

               return catBinder;//

       }

       @Override

       publicvoid onDestroy()

      {

            timer.cancel();

      }

}


客户端访问AIDL Service

首先复制service端AIDL接口文件到客户端应用中

 

然后访问service

public class AidlClient extends Activity

{

    privateICat catService;

   privateButton get;

   EditTextcolor, weight;

  privateServiceConnection conn = new ServiceConnection()

   {

          @Override

           publicvoid onServiceConnected(ComponentName name  ,IBinder service)

          {

                  //获取远程ServiceonBind方法返回的对象的代理

                 catService= ICat.Stub.asInterface(service);

          }

 

            @Override

           publicvoid onServiceDisconnected(ComponentName name)

          {

                   catService= null;

          }

    };

 

  @Override

   publicvoid onCreate(Bundle savedInstanceState)

   {

          super.onCreate(savedInstanceState);

           setContentView(R.layout.main);

 

          get= (Button) findViewById(R.id.get);

         color= (EditText) findViewById(R.id.color);

        weight= (EditText) findViewById(R.id.weight);

        //创建所需绑定的ServiceIntent

       Intentintent = new Intent();

       intent.setAction("org.crazyit.aidl.action.AIDL_SERVICE");

       //绑定远程Service

     bindService(intent,conn, Service.BIND_AUTO_CREATE);

 

     get.setOnClickListener(newOnClickListener()

      {

              @Override

              publicvoid onClick(View arg0)

               {

                     try

                     {

                           //获取、并显示远程Service的状态

                          color.setText(catService.getColor());

                          weight.setText(catService.getWeight()+ "");

                    }

                    catch(RemoteException e)

                    {

                          e.printStackTrace();

                     }

                }

         });

    }

}