转载

四大组件之Service初步

作为四大组件之一,所处重要地位可想而知。但是它并不像Activity那样可以所见,而是在后台默默的为应用程序服务着。那么到底什么是Service呢?

四大组件之Service初步

上面的官方文档说的很清楚了,Service不是一个线程,是主程序的一部分,需要调用Context.startService()来启动它,如果退出应用时,Service进程并没有结束,它仍然在后台行。比如我们在执行下载应用的时候,有可能去看新闻,正是有了Service,我们可以切换到新闻客户端来阅读新闻,而下载任务在后台被Service所执行。

Service生命周期,看下官网上的表述:

四大组件之Service初步

上面说Service有两种启动方式,分别是Context.startService(),Context.bindService()。下面简单的介绍这两种启动过程:

Context.startService():onCreate() => onStartCommand() => Context.stopService() || stopSelf() => onDestroy()

Context.bindService():onCreate() => onBind() => onUnbind() => onDestroy()

注意:

通过Context.startService()方式启动后,访问者与Service之间没有关联,即使访问者退出了,Service也仍然运行。

通过Context.bindService()方式启动后,访问者与Service绑定在一起,访问者一旦退出,Service就终止了。

这里分享一个小技巧,因为网络原因,我们查看android sdk下的文档时,非常慢(我用的是Chrome 49.0.26XXX),当然如果翻墙或者用VPN也可以,但是这都需要在有网下访问。由于我们在查看文档时,需要访问网络造成的,所以导致非常卡顿(断网情况下也是非常慢)。我们可以用Firefox浏览器打开文档,然后选择"开发者"工具中的"脱机工作",可以完美秒开文档。

下面通过demo简单的介绍Service用法。布局文件很简单:

[java]view plain copy
 print?四大组件之Service初步四大组件之Service初步
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     tools:context="com.example.service.MainActivity"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical">  
  7.   
  8.     <Button   
  9.         android:id="@+id/createService"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:text="启动服务"  
  13.         />  
  14.     <Button  
  15.         android:id="@+id/stopService"  
  16.         android:layout_height="wrap_content"  
  17.         android:layout_width="match_parent"  
  18.         android:text="停止服务" />  
  19.     <Button  
  20.         android:id="@+id/bindService"  
  21.         android:layout_height="wrap_content"  
  22.         android:layout_width="match_parent"  
  23.         android:text="绑定服务" />  
  24.     <Button  
  25.         android:id="@+id/ubindService"  
  26.         android:layout_height="wrap_content"  
  27.         android:layout_width="match_parent"  
  28.         android:text="解除绑定服务" />  
  29.     <Button   
  30.         android:id="@+id/status"  
  31.         android:layout_width="match_parent"  
  32.         android:layout_height="wrap_content"  
  33.         android:text="T的状态信息"  
  34.         />  
  35. </LinearLayout>  
需要有一个我们自己的Service类:

[java]view plain copy
 print?四大组件之Service初步四大组件之Service初步
  1. public class MyService extends Service {  
  2.       
  3.     private boolean bool = true;  
  4.     private int T;  
  5.     private MyBind mbind = new MyBind();  
  6.       
  7.     public class MyBind extends Binder{   //实现具体业务逻辑  
  8.         public int getT(){  
  9.          Log.d("MyBind","Mybind");  
  10.          //实现具体的逻辑  
  11.          return T;  
  12.         }  
  13.     }  
  14.     @Override  
  15.     public IBinder onBind(Intent intent) {   //返回IBinder对象  
  16.         // TODO 自动生成的方法存根  
  17.         return mbind;  
  18.     }  
  19.       
  20.     public boolean onUnbind(Intent intent){  //解除绑定的时候回调  
  21.         Log.d("onUnbind","onUnbind");  
  22.         return true;  
  23.     }  
  24.     public void onCreate(){ //Service第一次被创建时回调。多次启动已有的Service组件时,将直接回调onStartCommand(),而不会再次回调onCreate()  
  25.         super.onCreate();  
  26.         Log.d("onCreate","onCreate()");  
  27.         new Thread(new Runnable() {           
  28.             @Override  
  29.             public void run() {  
  30.                 // TODO 自动生成的方法存根         
  31.                 while(bool){  
  32.                     try {  
  33.                         Thread.sleep(6000);  
  34.                     } catch (InterruptedException e) {  
  35.                         // TODO 自动生成的 catch 块  
  36.                         e.printStackTrace();  
  37.                     }  
  38.                     T = new Random().nextInt(1000);  
  39.                 }  
  40.             }  
  41.         }).start();  
  42.     }  
  43.       
  44.      public int onStartCommand(Intent intent,int flags,int startId){  //客户端每次调用startService()启动该Service时回调此方法  
  45.         Log.d("onStartCommand","onStartCommand");  
  46.         return super.onStartCommand(intent, flags, startId);  
  47.           
  48.     }  
  49.       
  50.     public void onDestroy(){  //Service关闭时回调该方法  
  51.         super.onDestroy();  
  52.         Log.d("onDestory","onDestory()");  
  53.     }  
  54.   
  55. }  
MainActivity:

[java]view plain copy
 print?四大组件之Service初步四大组件之Service初步
  1. public class MainActivity extends Activity implements OnClickListener{  
  2.       
  3.     private Button startButton;  
  4.     private Button stopButton;  
  5.     private Button bindService;  
  6.     private Button ubindService;  
  7.     private Button status;  
  8.     private MyService.MyBind mbind;  
  9.     ServiceConnection conn = new ServiceConnection() {  
  10.           
  11.         @Override  
  12.         public void onServiceDisconnected(ComponentName name) {  
  13.             // TODO 自动生成的方法存根  
  14.               
  15.         }  
  16.           
  17.         @Override  
  18.         public void onServiceConnected(ComponentName name, IBinder service) {  
  19.             // TODO 自动生成的方法存根  
  20.             mbind = (MyService.MyBind)service;  
  21.         }  
  22.     };  
  23.     @Override  
  24.     protected void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);  
  26.         setContentView(R.layout.activity_main);  
  27.         startButton = (Button)findViewById(R.id.createService);  
  28.         stopButton = (Button)findViewById(R.id.stopService);  
  29.         bindService = (Button)findViewById(R.id.bindService);  
  30.         status = (Button)findViewById(R.id.status);  
  31.         ubindService = (Button)findViewById(R.id.ubindService);  
  32.           
  33.         startButton.setOnClickListener(this);  
  34.         stopButton.setOnClickListener(this);  
  35.         bindService.setOnClickListener(this);  
  36.         ubindService.setOnClickListener(this);  
  37.         status.setOnClickListener(this);  
  38.     }  
  39.   
  40.     @SuppressLint("ShowToast")  
  41.     @Override  
  42.     public void onClick(View v) {  
  43.         // TODO 自动生成的方法存根  
  44.         switch (v.getId()) {  
  45.         case R.id.createService:  //通过Context.startService()启动服务  
  46.             Intent intentstart = new Intent(MainActivity.this,MyService.class);  
  47.             startService(intentstart);  
  48.             break;  
  49.   
  50.         case R.id.stopService:   //停止服务  
  51.             Intent intentstop = new Intent(MainActivity.this,MyService.class);  
  52.             stopService(intentstop);  
  53.             break;  
  54.         case R.id.bindService:   //绑定服务  
  55.             Intent bindintent = new Intent(MainActivity.this,MyService.class);  
  56.             bindService(bindintent, conn, 0); //如果指定flags为0时,若想启动服务,则必须通过<span style="font-family: Arial, Helvetica, sans-serif;">Context.startService()启动  
  57.             break;  
  58.         case R.id.ubindService:  //取消绑定  
  59.             unbindService(conn);  
  60.             break;  
  61.         case R.id.status:  
  62.             Toast.makeText(MainActivity.this,"T的值为:"+mbind.getT(),Toast.LENGTH_SHORT).show();  
  63.         default:  
  64.             break;  
  65.         }  
  66.     }  
  67. }  

四大组件都需要在AndroidManifest.xml中注册:

[java]view plain copy
 print?四大组件之Service初步四大组件之Service初步
  1. <application  
  2.     ... >  
  3.     ...  
  4.     ...  
  5.     <service  
  6.         android:name="com.example.service.MyService">  
  7.     </service>  
  8.     ...  
  9.     ...  
  10. </application>  
运行程序:(就不通过日志分析,通过查看正在运行的Service比较直接)


四大组件之Service初步


那么如何把Activity与Service绑定呢?

需要用到public abstract booleanbindService(Intent service,ServiceConnection conn, int flags):

分析上面三个参数的含义(详细可以查看API)

service:通过Intent指定要启动的Service

conn:该参数是一个ServiceConnection对象,用于监听访问者与Service之间的连接情况。当访问者与Service成功连接时,回调该对象的onServiceConnected(ComponentName name, IBinder service)方法;当Service与访问者之间断开连接时回调该对象的onServiceDisconnected(ComponentName name)方法。

flags:指定绑定时是否自动创建Service(当Service还未创建),该参数可以是0(不自动创建)或BIND_AUTO_CREATE(自动创建),该参数可以自己模拟。由于上面绑定服务时,指定flags为0,所以若想点击"T的状态信息"按钮时,必须先点击"启动服务"按钮。

下面看下效果:

四大组件之Service初步

MyService中,设置T为随机数,MyBind类中的getT()用于返回T,onBind()返回IBinder对象,当访问者与Service成功连接时,onServiceConnected(ComponentName name, IBinder service)方法中会获得onBind()中返回的IBinder对象,然后调用MyBind类中的getT()方法,获得T,这就是上面的简单实现。由于本人水平有限,上面有误,请指正,不甚感激!

 总结:

1.Service需要在AndroidManifest.xml注册才可以生效

2.IBinder是访问者与Service之间信息交流的信使

3.Service两种启动方式以及不同点

正文到此结束
Loading...