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 class14 public class MyBinder extends Binder {15 // Any methods you can defined.16 public int getValue() {17 return i;18 }19 }20 21 @Override22 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 @Override42 public IBinder onBind(Intent intent) {43 return myBinder;44 }45 46 @Override47 public boolean onUnbind(Intent intent) {48 Log.d("David", "intent = " + intent);49 return super.onUnbind(intent);50 }51 52 @Override53 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 @Override27 public void onServiceDisconnected(ComponentName name) {28 Log.d("David", "ServiceDisconnected!");29 }30 31 @Override32 public void onServiceConnected(ComponentName name, IBinder service) {33 Log.d("David", "ServiceConnected!");34 myBinder = (MyBinder) service;35 }36 };37 38 @Override39 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 @Override50 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 @Override62 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 @Override74 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 @Override16 public String getColor() throws RemoteException {17 return sBuffer.toString();18 }19 20 }21 22 @Override23 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 @Override42 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 @Override28 public void onServiceDisconnected(ComponentName name) {29 Log.d("David", "ServiceDisconnected!");30 }31 32 @Override33 public void onServiceConnected(ComponentName name, IBinder service) {34 Log.d("David", "ServiceConnected!");35 myBinder = IServer.Stub.asInterface(service);36 }37 };38 39 @Override40 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 @Override51 public void onClick(View v) {52 Intent intent = new Intent("android.intent.action.main.DAVID");53 bindService(intent, connection, BIND_AUTO_CREATE); // Bind54 Log.d("David", "Bind service!");55 btnUnbindService.setEnabled(true);56 btnGetValue.setEnabled(true);57 }58 });59 60 btnUnbindService.setOnClickListener(new OnClickListener() {61 62 @Override63 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 @Override75 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,比较简单,留做笔记吧,希望对同学们有帮助。