2013-12-30 18:16:11 

1. Service和Activty都是从Context里面派生出来的,因此都可以直接调用getResource(),getContentResolver()等方法。

2. 启动Service有两种方式:

    2.1 startService():该方法启动Service,访问者和Service之间没有关联,一旦启动,即使访问者退出,Service依然运行;

    2.2 bindService():该方法启动Service,访问者和Service绑定在一起,一旦访问者退出,Service随即退出。

3. onCreate()只会被调用一次,onStartCommand()方法每次Service被启动时都会被调用。

4. 绑定本地Service并与之通信:

    4.1 当程序通过startService()、stopService()来启动、停止Service时,Service和访问者之间无法进行通信和数据交换。

    4.2 如果要实现访问者和Service之间通信、交换数据,那么需要使用bindService()和unBindService()来启动、停止Service。

5. 程序实例:

先来一张图:

MyService.java

 1 package com.example.localservice;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.Binder;
 6 import android.os.IBinder;
 7 import android.util.Log;
 8 
 9 public class MyService extends Service {
10     private int i;
11     private MyBinder myBinder;
12 
13     // Define our own Binder class
14     public class MyBinder extends Binder {
15         // Any methods you can defined.
16         public int getValue() {
17             return i;
18         }
19     }
20 
21     @Override
22     public void onCreate() {
23         // Something the service doing.
24         super.onCreate();
25         myBinder = new MyBinder();
26         new Thread() {
27             public void run() {
28                 while (true) {
29                     try {
30                         Thread.sleep(1000);
31                     } catch (InterruptedException e) {
32                         e.printStackTrace();
33                     }
34                     i++;
35                 }
36             };
37         }.start();
38     }
39 
40     // Return our own Binder object.
41     @Override
42     public IBinder onBind(Intent intent) {
43         return myBinder;
44     }
45 
46     @Override
47     public boolean onUnbind(Intent intent) {
48         Log.d("David", "intent = " + intent);
49         return super.onUnbind(intent);
50     }
51 
52     @Override
53     public void onDestroy() {
54         Log.d("David", "-------onDestroy!");
55         super.onDestroy();
56     }
57 
58 }

MainActivity.java

 1 package com.example.localservice;
 2 
 3 import android.app.Activity;
 4 import android.content.ComponentName;
 5 import android.content.Intent;
 6 import android.content.ServiceConnection;
 7 import android.os.Bundle;
 8 import android.os.IBinder;
 9 import android.util.Log;
10 import android.view.View;
11 import android.view.View.OnClickListener;
12 import android.widget.Button;
13 import android.widget.Toast;
14 
15 import com.example.localservice.MyService.MyBinder;
16 
17 public class MainActivity extends Activity {
18     private MyBinder myBinder;
19     private Button btnBindService;
20     private Button btnUnbindService;
21     private Button btnGetValue;
22 
23     ServiceConnection connection = new ServiceConnection() {
24 
25         // Two call-back methods.
26         @Override
27         public void onServiceDisconnected(ComponentName name) {
28             Log.d("David", "ServiceDisconnected!");
29         }
30 
31         @Override
32         public void onServiceConnected(ComponentName name, IBinder service) {
33             Log.d("David", "ServiceConnected!");
34             myBinder = (MyBinder) service;
35         }
36     };
37 
38     @Override
39     protected void onCreate(Bundle savedInstanceState) {
40         super.onCreate(savedInstanceState);
41         setContentView(R.layout.activity_main);
42         btnBindService = (Button) findViewById(R.id.btn_bind_service);
43         btnUnbindService = (Button) findViewById(R.id.btn_unbind_service);
44         btnUnbindService.setEnabled(false);
45         btnGetValue = (Button) findViewById(R.id.btn_get_value);
46         btnGetValue.setEnabled(false);
47         btnBindService.setOnClickListener(new OnClickListener() {
48 
49             @Override
50             public void onClick(View v) {
51                 Intent intent = new Intent("android.intent.action.DAVID");
52                 bindService(intent, connection, BIND_AUTO_CREATE); // Bind service with connection.
53                 Log.d("David", "Bind service!");
54                 btnUnbindService.setEnabled(true);
55                 btnGetValue.setEnabled(true);
56             }
57         });
58 
59         btnUnbindService.setOnClickListener(new OnClickListener() {
60 
61             @Override
62             public void onClick(View v) {
63                 if (connection != null) {
64                     // stopService(new Intent("android.intent.action.DAVID"));
65                     unbindService(connection);
66                     Log.d("David", "Unbind service!");
67                 }
68             }
69         });
70 
71         btnGetValue.setOnClickListener(new OnClickListener() {
72 
73             @Override
74             public void onClick(View v) {
75                 if (myBinder == null) {
76                     Toast.makeText(MainActivity.this,
77                             "Please bind service first!", Toast.LENGTH_LONG)
78                             .show();
79                     return;
80                 }
81                 Log.d("David", "Got value = " + myBinder.getValue());
82             }
83         });
84     }
85 
86 }

代码和操作很简单,看button title即可。源码下载

遇到一个问题:先Bind service,然后点击第三个button,发现可以取到值,此时点击第二个button,unbind service,再点击第三个button发现还是能取到值,这个还得在研究研究,当然了,有知道答案的言语一声。

6. Android的远程调用

Android的远程调用和Java的RMI类似,一样都是先定义一个远程调用接口,然后为该接口提供一个实现类即可。与RMI不同的是,客户端访问Service时,Android并不是直接返回Serivce对象给客户端,而是将一个回调对象IBinder通过onBind()方法返回给客户端。

7. 本地调用Serivce,onBind()方法返回的是IBinder对象,远程调用返回的是IBinder对象的代理。

程序实例:Server端

IServer.aidl

1 package com.example.serviceserver;
2   
3 interface IServer{
4    String getColor();
5 }

ServiceServer.java

 1 package com.example.serviceserver;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.IBinder;
 6 import android.os.RemoteException;
 7 
 8 public class ServiceServer extends Service {
 9     private int i;
10     private StringBuffer sBuffer = new StringBuffer("ServiceServer");
11     private MyBinder myBinder;
12 
13     public class MyBinder extends IServer.Stub {
14 
15         @Override
16         public String getColor() throws RemoteException {
17             return sBuffer.toString();
18         }
19 
20     }
21 
22     @Override
23     public void onCreate() {
24         super.onCreate();
25         myBinder = new MyBinder();
26         new Thread() {
27             public void run() {
28                 while (true) {
29                     try {
30                         Thread.sleep(1000);
31                     } catch (InterruptedException e) {
32                         e.printStackTrace();
33                     }
34                     sBuffer.append(i + "");
35                     i++;
36                 }
37             };
38         }.start();
39     }
40 
41     @Override
42     public IBinder onBind(Intent intent) {
43         return myBinder;
44     }
45 }

Client端:

IServer.aidl

1 package com.example.serviceserver;
2   
3 interface IServer{
4    String getColor();
5 }

MainActivity.java

 1 package com.example.serviceclient;
 2 
 3 import android.app.Activity;
 4 import android.content.ComponentName;
 5 import android.content.Intent;
 6 import android.content.ServiceConnection;
 7 import android.os.Bundle;
 8 import android.os.IBinder;
 9 import android.os.RemoteException;
10 import android.util.Log;
11 import android.view.View;
12 import android.view.View.OnClickListener;
13 import android.widget.Button;
14 import android.widget.Toast;
15 
16 import com.example.serviceserver.IServer;
17 
18 public class MainActivity extends Activity {
19     private IServer myBinder;
20     private Button btnBindService;
21     private Button btnUnbindService;
22     private Button btnGetValue;
23 
24     ServiceConnection connection = new ServiceConnection() {
25 
26         // Two call-back methods.
27         @Override
28         public void onServiceDisconnected(ComponentName name) {
29             Log.d("David", "ServiceDisconnected!");
30         }
31 
32         @Override
33         public void onServiceConnected(ComponentName name, IBinder service) {
34             Log.d("David", "ServiceConnected!");
35             myBinder = IServer.Stub.asInterface(service);
36         }
37     };
38 
39     @Override
40     protected void onCreate(Bundle savedInstanceState) {
41         super.onCreate(savedInstanceState);
42         setContentView(R.layout.activity_main);
43         btnBindService = (Button) findViewById(R.id.btn_bind_service);
44         btnUnbindService = (Button) findViewById(R.id.btn_unbind_service);
45         btnUnbindService.setEnabled(false);
46         btnGetValue = (Button) findViewById(R.id.btn_get_value);
47         btnGetValue.setEnabled(false);
48         btnBindService.setOnClickListener(new OnClickListener() {
49 
50             @Override
51             public void onClick(View v) {
52                 Intent intent = new Intent("android.intent.action.main.DAVID");
53                 bindService(intent, connection, BIND_AUTO_CREATE); // Bind
54                 Log.d("David", "Bind service!");
55                 btnUnbindService.setEnabled(true);
56                 btnGetValue.setEnabled(true);
57             }
58         });
59 
60         btnUnbindService.setOnClickListener(new OnClickListener() {
61 
62             @Override
63             public void onClick(View v) {
64                 if (connection != null) {
65                     // stopService(new Intent("android.intent.action.DAVID"));
66                     unbindService(connection);
67                     Log.d("David", "Unbind service!");
68                 }
69             }
70         });
71 
72         btnGetValue.setOnClickListener(new OnClickListener() {
73 
74             @Override
75             public void onClick(View v) {
76                 if (myBinder == null) {
77                     Toast.makeText(MainActivity.this,
78                             "Please bind service first!", Toast.LENGTH_LONG)
79                             .show();
80                     return;
81                 }
82                 try {
83                     Log.d("David", "Got value = " + myBinder.getColor());
84                 } catch (RemoteException e) {
85                     e.printStackTrace();
86                 }
87             }
88         });
89     }
90 
91 }

还是这个问题:先Bind service,然后点击第三个button,发现可以取到值,此时点击第二个button,unbind service,再点击第三个button发现还是能取到值。有知道的同学欢迎拍砖。

源码下载

先运行SeriviceServer,然后再启动ServiceClient,比较简单,留做笔记吧,希望对同学们有帮助。

 posted on 2013-12-31 16:01  wlrhnh  阅读(415)  评论(1编辑  收藏  举报