先来一点基础知识:
Service 是android的四大组件之一,与Activity同属于一个级别,它是运行在后台进行服务的组件(例如在后台播放的音乐,播放音乐的同时并不影响其他操作)。Service与Activity不同,Service没有界面。
Service虽然在后台运行,但是却与Activity一样运行在主程序中,因此不可在Service中进行耗时的操作。如果需要耗时操作的时候,可以开启子线程来操作。
Service的两种用法及其生命周期:
1.startService 开启服务
2.bindService 绑定服务
上图是这两种用法的生命周期图:
1、启动方式:onCreate()->onStartCommand()->onStop()->onDestroy()
2、绑定方式:onCreate()->onBind()->onUnBind()->onDestroy()
启动服务:一般从活动中调用 startService() ==> 服务调用 onCreate()(创建时只调用一次)==>onStartCommand() (可调用多次)
停止服务:一般从活动中调用 stopService() ==> 服务调用 onDestroy() (只调用一次) 或 直接在服务中调用stopSelf()来停止,如果有绑定服务,得先解绑,才能停止服务
使用方法一:启动服务
例子:服务与Activity的交互
1.在MainActivity中设置两个Button,分别启动服务和停止服务。
1 importandroid.content.Intent;2 importandroid.os.Bundle;3 importandroid.support.v7.app.ActionBarActivity;4 importandroid.view.Menu;5 importandroid.view.MenuItem;6 importandroid.view.View;7
8 public class MainActivity extendsActionBarActivity {9 int number=38;10 @Override11 protected voidonCreate(Bundle savedInstanceState) {12 super.onCreate(savedInstanceState);13 setContentView(R.layout.activity_main);14 }15
16 public voiddoButton(View v) {17 Intent intent=newIntent();18 switch(v.getId()) {19 caseR.id.button1:20 intent.setAction("com.robin.testservice2.action");21 intent.putExtra("number", number);22 startService(intent);//启动服务
23 number++;24 break;25
26 caseR.id.button2:27 intent.setAction("com.robin.testservice2.action");28 stopService(intent);//停止服务
29 break;30 default:31 break;32 }33 }34 }
2.建一个Service的子类----这是在执行每两秒cnt自动减1的操作,其代码如下:
1 importandroid.app.Service;2 importandroid.content.Intent;3 importandroid.media.MediaPlayer;4 importandroid.os.IBinder;5 importandroid.util.Log;6
7 public class MyService extendsService{8 protected static final String TAG = "robin debug";9 MediaPlayer mp;10 Thread printThread;11 int cnt=-1;12 boolean active=false;13 @Override14 publicIBinder onBind(Intent intent) {15 return null;16 }17
18 @Override19 public voidonCreate() {20 Log.e(TAG,"service create");21 super.onCreate();22 }23
24 @Override25 public int onStartCommand(Intent intent, int flags, intstartId) {26 Log.e(TAG,"service start command");27 cnt=intent.getIntExtra("number", -1);28 active=true;29 printThread=newThread(){30 @Override31 public voidrun() {32 while(active){33 cnt--;34 try{35 Thread.sleep(2000);36 } catch(InterruptedException e) {37 e.printStackTrace();38 }39 Log.e(TAG,"progress value--------->"+cnt);40 }41 }42 };43 printThread.start();44 return super.onStartCommand(intent, flags, startId);45 }46
47 @Override48 public voidonDestroy() {49 active=false;50 super.onDestroy();51 Log.e(TAG,"service destroy");52 }53 }
布局文件
1
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent" >
5
6
8 android:layout_width="wrap_content"
9 android:layout_height="wrap_content"
10 android:text="@string/hello_world" />
11
12
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content"
16 android:layout_alignLeft="@+id/textView1"
17 android:layout_below="@+id/textView1"
18 android:layout_marginLeft="47dp"
19 android:layout_marginTop="24dp"
20 android:text="启动服务"
21 android:onClick="doButton"/>
22
23
25 android:layout_width="wrap_content"
26 android:layout_height="wrap_content"
27 android:layout_alignLeft="@+id/button1"
28 android:layout_below="@+id/button1"
29 android:layout_marginTop="60dp"
30 android:text="停止服务"
31 android:onClick="doButton"/>
32
33
以上的操作过程为,在Activity界面点击启动服务(startService(intent);)--->在MyService 中会执行
使用方法二:绑定服务
例子:Service与Activity之间进行通信
先来看看方法之间的调用顺序/过程:
上图中的代码:
ICount.java 类:
1 packagecom.robin.testservice3;2
3
4 public interface ICount { //描述需要的行为(功能)
5 public intgetCount();6 public void setCount(intcnt);7 }
MainActivity.java
1 packagecom.robin.testservice3;2
3 importandroid.content.ComponentName;4 importandroid.content.Intent;5 importandroid.content.ServiceConnection;6 importandroid.os.Bundle;7 importandroid.os.IBinder;8 importandroid.support.v7.app.ActionBarActivity;9 importandroid.view.Menu;10 importandroid.view.MenuItem;11 importandroid.view.View;12 importandroid.widget.TextView;13
14 public class MainActivity extendsActionBarActivity {15 privateICount count;16 private class MyConn implementsServiceConnection{17
18 @Override19 public voidonServiceConnected(ComponentName name, IBinder binder) {20 count=(ICount) binder;21 }22
23 @Override24 public voidonServiceDisconnected(ComponentName name) {25 count=null;26 }27 }28 MyConn conn=newMyConn();29 TextView txt;30 @Override31 protected voidonCreate(Bundle savedInstanceState) {32 super.onCreate(savedInstanceState);33 setContentView(R.layout.activity_main);34 Intent service=new Intent("com.robin.testservice3.action");35 bindService(service, conn, BIND_AUTO_CREATE);36 txt=(TextView)findViewById(R.id.result);37 }38
39 @Override40 public booleanonCreateOptionsMenu(Menu menu) {41 getMenuInflater().inflate(R.menu.main, menu);42 return true;43 }44
45 @Override46 public booleanonOptionsItemSelected(MenuItem item) {47 int id =item.getItemId();48 if (id ==R.id.action_settings) {49 return true;50 }51 return super.onOptionsItemSelected(item);52 }53
54 public voiddoButton(View view ){55 switch(view.getId()) {56 caseR.id.button1:57 txt.setText("来自service子线程的计数值:"+count.getCount());58 break;59 caseR.id.button2:60 count.setCount(1000);61 break;62 default:63 break;64 }65 }66 @Override67 protected voidonDestroy() {68 unbindService(conn);69 super.onDestroy();70 }71 }
MyService.java
1 packagecom.robin.testservice3;2
3 importandroid.app.Service;4 importandroid.content.Intent;5 importandroid.os.Binder;6 importandroid.os.IBinder;7 importandroid.util.Log;8
9 public class MyService extendsService{10 protected static final String TAG = "robin debug";11 private boolean active=false;12 private int cnt=0;13 private class MyBinder extends Binder implementsICount{14
15 @Override16 public intgetCount() {17 returncnt;18 }19 @Override20 public void setCount(intcnt) {21 MyService.this.cnt=cnt;22 }23 }24 MyBinder binder=newMyBinder();25
26 @Override27 publicIBinder onBind(Intent intent) {28 returnbinder;29 }30
31 @Override32 public voidonCreate() {33 new Thread(newRunnable() {34
35 @Override36 public voidrun() {37 active=true;38 while(active){39 cnt++;40 try{41 Thread.sleep(2000);42 } catch(InterruptedException e) {43 e.printStackTrace();44 }45 Log.e(TAG,"service thread :cnt----->"+cnt);46
47 }48 }49 }).start();50 super.onCreate();51 }52 @Override53 public voidonDestroy() {54 Log.e(TAG,"service call onDestroy");55 active=false;56 super.onDestroy();57 }58 }
布局文件:
1
2 xmlns:tools="http://schemas.android.com/tools"
3 android:id="@+id/LinearLayout1"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent"
6 android:orientation="vertical">
7
8
10 android:layout_height="wrap_content"
11 android:text="测试绑定使用service" />
12
13
15 android:layout_width="wrap_content"
16 android:layout_height="wrap_content"
17 android:text="读service端子线程的计数值"
18 android:onClick="doButton"/>
19
20
22 android:layout_width="wrap_content"
23 android:layout_height="wrap_content"
24 android:text="修改service端子线程的计数值"
25 android:onClick="doButton"/>
26
27
29 android:layout_width="wrap_content"
30 android:layout_height="wrap_content"
31 android:text="TextView" />
32
33