介绍
Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
Service有两种状态,“启动的”和“绑定”。
使用方法
看下关于Service两张比较经典的图
####简单实例
AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
<activity android:name=".MyActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <service android:name=".MyService" android:enabled="true"/> <!--四大组件都要在AndroidManifest中申明一把 --> </application>
|
MyActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| public class MyActivity extends Activity implements View.OnClickListener, ServiceConnection { public static String TAG = "MyActivity";
Intent intent;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.main);
Log.e(TAG, "MyActivity OnCreate"); intent = new Intent(MyActivity.this, MyService.class);
findViewById(R.id.bt_startservice).setOnClickListener(this); findViewById(R.id.bt_stopservice).setOnClickListener(this); findViewById(R.id.bt_bindservice).setOnClickListener(this); findViewById(R.id.bt_unbindservice).setOnClickListener(this); } public void onClick(View view) { Log.e(TAG,"OnClick"); switch (view.getId()) { case R.id.bt_startservice: Log.e(TAG, "start Service"); startService(intent); break; case R.id.bt_stopservice: stopService(intent); break; case R.id.bt_bindservice: bindService(intent, this, Context.BIND_AUTO_CREATE); break; case R.id.bt_unbindservice: unbindService(this); break; } }
@Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { Log.e(TAG, "onServiceConnected"); }
@Override public void onServiceDisconnected(ComponentName componentName) { Log.e(TAG, "onServiceDisconnected"); } }
|
MyService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| public class MyService extends Service { public static String TAG = "MyService";
@Override public void onCreate() { super.onCreate(); Log.e(TAG, "MyService onCreate"); }
@Override public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId); }
@Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy"); }
@Override public IBinder onBind(Intent intent) { Log.e(TAG, "onBind"); return new Binder(); }
@Override public boolean onUnbind(Intent intent) { Log.e(TAG, "onUnbind"); return super.onUnbind(intent); }
@Override public void onRebind(Intent intent) { Log.e(TAG, "onRebind"); super.onRebind(intent); } }
|
测试结果
- 启动服务,停止服务
- 绑定服务,解绑服务
- 启动服务,绑定服务,解绑服务
注意:这里最后Service是没有onDestory的
- 启动服务,绑定服务,解绑服务,停止服务
Binder使用,这个很关键
MyService.java中修改
1 2 3 4 5 6 7 8 9
| public IBinder onBind(Intent intent) { Log.e(TAG, "onBind"); return new MyBinder(); } class MyBinder extends Binder { public void sayHello() { Log.e(TAG,"I am a binder, hi"); } }
|
MyActivity.java中修改
1 2 3 4 5
| public void onServiceConnected(ComponentName componentName, IBinder iBinder) { Log.e(TAG, "onServiceConnected"); MyService.MyBinder binder = (MyService.MyBinder) iBinder; ((MyService.MyBinder) iBinder).sayHello(); }
|
然后执行:绑定服务,解绑服务
通过这个Binder,再加上Callback,可以实现对Service内部状态的监听
先定义一个接口,然后创建get与set,在onBinder方法中定义一个线程不停的发送数据
1 2 3 4 5 6 7 8 9 10 11 12
| public interface Callback() { public void onDateChanged(String data) { } }
public void setCallback(Callback callback) { this.callback = callback; }
public Callback getCallback() { return callback; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public IBinder onBind(Intent intent) { Log.e(TAG, "onBind");
running = true; new Thread(new Runnable() { @Override public void run() { while (running) { try { Thread.sleep(1000); i++; String str = "send: " + i ; callback.onDateChanged(str); } catch (InterruptedException e) { e.printStackTrace(); } Log.e(TAG, "Service is Running ... "); } } }).start(); return new MyBinder(); }
|
然后在MyBinder类中定义一个getService方法
1 2 3
| public MyService getSetvice() { return MyService.this; }
|
然后在onServiceConnected中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public void onServiceConnected(ComponentName componentName, IBinder iBinder) { Log.e(TAG, "onServiceConnected"); MyService.MyBinder binder = (MyService.MyBinder) iBinder; MyService myservice = binder.getService(); myservice.setCallback(new MyService.Callback() { @Override public void onDateChanged(String str) { Message msg = new Message(); msg.arg1 = 1; Bundle bundle = new Bundle(); bundle.putString("data", str); msg.setData(bundle); handler.sendMessage(msg); } }); }
|
通过这种方式就可以实现Service和Activity的通信工作,不难看出,Binder在其中起着非常重要的角色。
Android中进程间通信,从JAVA到C++基本上都是用Binder来实现的,上层使用的AIDL下一篇介绍一下,