27、Service

1服务可以通过startservice的方法 开启。通过stopservice的方法 停止。

服务有一个特点: 只会一次onCreate()方法一旦被创建出来,以后oncreate() 就不会再被执行了,
以后再去开启服务 只会执行onstart()方法,当服务被停止的时候 onDestroy();

2 服务通过bindservice的方法开启
首先 如果服务不存在 就会执行 oncreate() ->onbind()方法
一旦服务绑定成功 以后再去执行 bindsercie() 就不会在重新创建 或者绑定服务了();

如果我们现实的调用unbindservice()的方法 ,首先 on unbind()方法 -> ondestroy() ;
服务只能被解除绑定一次 多次解除绑定服务 程序会出异常.


开启服务 (startservice)
服务一旦开启与调用者没有任何的关系 , 调用着的activity 即便是退出了 也不会影响
后台的service的运行.
在activity里面 不能去调用服务里面的方法 (因为Service是框架new出来的,activity无法获取到该Service的引用).

通过绑定方式开启服务(bindservice)
服务跟调用者不求同生 ,但求同死.
如果调用者(activity)退出了 那他绑定的服务呢 也会跟着退出.

 

我们可以在activity里面调用服务里面的方法.

利用 serviceSonnection 接口 返回一个ibinder对象 , 拿着ibinder对象获取到服务里面方法的引用(自定义了一个接口信息) 调用服务里面的方法。

 

一个应用程序 一个进程里面 定义一个IService 的接口来描述方法

如果我们要调用另外一个进程 服务里面的方法 aidl(android interface defination language)

 

总结流程:

1.要想访问 一个服务里面的方法 我们需要用到 bindservice();
一 创建一个服务 这个服务里面有一个要被调用的方法.
二 定义一个接口IService , 接口里面的抽象方法 就是去调用service里面的方法。 
三 定义一个mybinder对象 extends IBinder对象 实现 我们声明的接口IService, 在onbind
方法里面把mybinder返回回去。
四 在activity里面 通过bindservice的方法开启服务。 
五 创建出来一个我们MyConn 实现 ServiceConnection接口 onserviceConnected的方法。
这个方法会有一个参数 这个参数就是 MyBinder的对象。 
六 把mybinder强制类型转化成 IServcie。
七 调用IService里面的方法。

范例:开启、停止、绑定、解除绑定、调用服务里面的方法。

1 public interface IService {
2     public void callMethodInService();
3 }

 

 1 import android.app.Activity;
 2 import android.content.ComponentName;
 3 import android.content.Context;
 4 import android.content.Intent;
 5 import android.content.ServiceConnection;
 6 import android.os.Bundle;
 7 import android.os.IBinder;
 8 import android.view.View;
 9 import android.view.View.OnClickListener;
10 import android.widget.Button;
11 
12 /**
13  * 通过startservice开启服务的生命周期。
14  * 利用bindservice调用服务里面的方法。
15  * @author dr
16  */
17 public class DemoActivity extends Activity implements OnClickListener {
18 
19     Button bt_start, bt_stop;
20     // 绑定服务 解除绑定服务
21     Button bt_bind_service, bt_unbind_service; 
22     Button bt_call_service;
23     Intent intent;
24     MyConn conn;
25     IService iService;
26 
27     @Override
28     public void onCreate(Bundle savedInstanceState) {
29         super.onCreate(savedInstanceState);
30         setContentView(R.layout.main);
31         
32         bt_start = (Button) this.findViewById(R.id.button1);
33         bt_stop = (Button) this.findViewById(R.id.button2);
34         bt_bind_service = (Button) this.findViewById(R.id.button3);
35         bt_unbind_service = (Button) this.findViewById(R.id.button4);
36         bt_call_service = (Button) this.findViewById(R.id.button5);
37         bt_start.setOnClickListener(this);
38         bt_stop.setOnClickListener(this);
39         bt_bind_service.setOnClickListener(this);
40         bt_unbind_service.setOnClickListener(this);
41         bt_call_service.setOnClickListener(this);
42         intent = new Intent(this, MyService.class);
43         conn = new MyConn();
44     }
45 
46     @Override
47     public void onClick(View v) {
48         switch (v.getId()) {
49         case R.id.button1: // 开启服务
50             startService(intent);
51             break;
52         case R.id.button2: // 停止服务
53             stopService(intent);
54             break;
55         case R.id.button3: // 绑定服务
56             bindService(intent, conn, Context.BIND_AUTO_CREATE);
57             break;
58         case R.id.button4: // 解除绑定服务
59             unbindService(conn);
60             break;
61         // 绑定开启
62         case R.id.button5: // 调用服务里面的方法
63             iService.callMethodInService();
64             break;
65         }
66     }
67 
68     private class MyConn implements ServiceConnection {
69         // 绑定一个服务成功的时候 调用 onServiceConnected
70         @Override
71         public void onServiceConnected(ComponentName name, IBinder service) {
72             // 绑定成功后,会返回这个IBinder对象(MyService中的onBind返回的)。
73             iService = (IService) service;
74         }
75 
76         @Override
77         public void onServiceDisconnected(ComponentName name) {
78 
79         }
80     }
81 
82     @Override
83     protected void onDestroy() {
84         unbindService(conn);
85         super.onDestroy();
86     }
87 
88 }

 

 1 import android.app.Service;
 2 import android.content.Intent;
 3 import android.os.Binder;
 4 import android.os.IBinder;
 5 
 6 public class MyService extends Service {
 7 
 8     @Override
 9     public IBinder onBind(Intent intent) {
10         System.out.println("on bind");
11         return new MyBinder();
12     }
13 
14     public class MyBinder extends Binder implements IService {
15         @Override
16         public void callMethodInService() {
17             sayHelloInService();
18         }
19     }
20 
21     /**
22      * 服务里面的一个方法
23      */
24     public void sayHelloInService() {
25         System.out.println("hello in service");
26     }
27 
28     @Override
29     public boolean onUnbind(Intent intent) {
30         System.out.println("on  unbind");
31         return super.onUnbind(intent);
32     }
33 
34     @Override
35     public void onCreate() {
36         System.out.println("oncreate");
37         super.onCreate();
38     }
39 
40     @Override
41     public void onStart(Intent intent, int startId) {
42         System.out.println("onstart");
43 
44         super.onStart(intent, startId);
45     }
46 
47     @Override
48     public void onDestroy() {
49         System.out.println("ondestroy");
50         super.onDestroy();
51     }
52 }

 

2.要想访问一个远程服务里的方法 需要用到aidl
一 创建一个服务 这个服务里面有一个要被调用的方法.
二 定义一个接口IService , 接口里面的抽象方法 就是去调用service里面的方法。 
把.java的后缀名改成aidl 把接口里面定义的访问权限的修饰符都给删除。
三 定义一个mybinder对象 extends IService.Stub, 在onbind方法里面把mybinder返回回去。
四 在activity里面 通过bindservice的方法开启服务。
五 创建出来一个我们MyConn 实现 ServiceConnection接口 onserviceConnected的方法,这个方法会有一个参数 这个参数就是MyBinder的对象。
六 IService = IService.Stub.asInterface(myBinder)。
七 调用IService的方法。

 

范例:采用aidl访问远程服务里面的方法

 

 

 1 import android.app.Service;
 2 import android.content.Intent;
 3 import android.os.IBinder;
 4 import android.os.RemoteException;
 5 
 6 /**
 7  * 采用aidl访问远程服务里面的方法 --- 远程服务
 8  * 调用着是:callremote Project。
 9  * @author dr
10  *
11  */
12 public class RemoteService extends Service {
13 
14     @Override
15     public IBinder onBind(Intent intent) {
16         return new MyBinder();
17     }
18 
19     private class MyBinder extends IService.Stub {
20         @Override
21         public void callMethodInService() throws RemoteException {
22             sayHelloInService();
23         }
24     }
25 
26     /**
27      * 服务里面的一个方法
28      */
29     public void sayHelloInService() {
30         System.out.println("hello in service");
31     }
32 
33     @Override
34     public void onCreate() {
35         System.out.println("remote service oncreate");
36         super.onCreate();
37     }
38 
39 }

 

1 // IService.aidl 文件
2 interface IService {
3  void callMethodInService();
4 }
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="cn.itcast.remoteservice"
 4     android:versionCode="1"
 5     android:versionName="1.0" >
 6 
 7     <uses-sdk android:minSdkVersion="8" />
 8 
 9     <application
10         android:icon="@drawable/ic_launcher"
11         android:label="@string/app_name" >
12         <service android:name=".RemoteService" >
13             <intent-filter >
14                 <action android:name="cn.itcast.remoteservice"/>
15             </intent-filter>
16         </service>
17     </application>
18 
19 </manifest>

 

 

 1 import cn.itcast.remoteservice.IService;
 2 import android.app.Activity;
 3 import android.content.ComponentName;
 4 import android.content.Intent;
 5 import android.content.ServiceConnection;
 6 import android.os.Bundle;
 7 import android.os.IBinder;
 8 import android.os.RemoteException;
 9 import android.view.View;
10 
11 /**
12  * 采用aidl访问远程服务里面的方法 --- 调用远程服务
13  * 调用着是:remoteservice Project。
14  * @author dr
15  *
16  */
17 public class DemoActivity extends Activity {
18     IService iService;
19     @Override
20     public void onCreate(Bundle savedInstanceState) {
21         super.onCreate(savedInstanceState);
22         setContentView(R.layout.main);
23         
24         Intent intent = new Intent();
25         intent.setAction("cn.itcast.remoteservice");
26         bindService(intent, new MyConn(), BIND_AUTO_CREATE);
27     }
28     
29     
30     public void click(View view){
31         try {
32             // 调用了远程服务的方法 
33             iService.callMethodInService();
34         } catch (RemoteException e) {
35             // TODO Auto-generated catch block
36             e.printStackTrace();
37         }
38     }
39     
40     private class MyConn implements ServiceConnection{
41 
42         @Override
43         public void onServiceConnected(ComponentName name, IBinder service) {
44             iService = IService.Stub.asInterface(service);
45         }
46 
47         @Override
48         public void onServiceDisconnected(ComponentName name) {
49             // TODO Auto-generated method stub
50         }
51         
52     }
53 }
1 // 把 远程服务 Demo中的 aidl文件复制过来。包路径要一致。
2 interface IService {
3  void callMethodInService();
4 }
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="cn.itcast.remoteservice"
 4     android:versionCode="1"
 5     android:versionName="1.0" >
 6 
 7     <uses-sdk android:minSdkVersion="8" />
 8 
 9     <application
10         android:icon="@drawable/ic_launcher"
11         android:label="@string/app_name" >
12         <service android:name=".RemoteService" >
13             <intent-filter >
14                 <action android:name="cn.itcast.remoteservice"/>
15             </intent-filter>
16         </service>
17     </application>
18 
19 </manifest>

 

范例:采用aidl挂断电话

 1 import java.lang.reflect.Method;
 2 import com.android.internal.telephony.ITelephony;
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.IBinder;
 6 import android.os.RemoteException;
 7 import android.view.View;
 8 
 9 /**
10  * 采用aidl挂断电话
11  * @author dr
12  */
13 public class DemoActivity extends Activity {
14     ITelephony iTelephony;
15 
16     /** Called when the activity is first created. */
17     @Override
18     public void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         setContentView(R.layout.main);
21 
22         try {
23             // 获取系统电话管理的服务
24             Method method = Class.forName("android.os.ServiceManager")
25                     .getMethod("getService", String.class);
26             IBinder binder = (IBinder) method.invoke(null,
27                     new Object[] { TELEPHONY_SERVICE });
28             iTelephony = ITelephony.Stub.asInterface(binder);
29         } catch (Exception e) {
30             e.printStackTrace();
31         }
32     }
33 
34     public void endcall(View view) {
35         try {
36             iTelephony.call("123");
37         } catch (RemoteException e) {
38             e.printStackTrace();
39         }
40         // iTelephony.call("123");
41     }
42 }
 1 /* //device/java/android/android/content/Intent.aidl
 2 **
 3 ** Copyright 2007, The Android Open Source Project
 4 **
 5 ** Licensed under the Apache License, Version 2.0 (the "License");
 6 ** you may not use this file except in compliance with the License.
 7 ** You may obtain a copy of the License at
 8 **
 9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 // NeighboringCellInfo.aidl
19 package android.telephony;
20 
21 parcelable NeighboringCellInfo;
1 <uses-permission android:name="android.permission.CALL_PHONE" />

 

 

 

posted on 2014-09-10 23:14  大米稀饭  阅读(302)  评论(0编辑  收藏  举报