• Service的两种用法及其生命周期


    先来一点基础知识:

      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 import android.content.Intent;
     2 import android.os.Bundle;
     3 import android.support.v7.app.ActionBarActivity;
     4 import android.view.Menu;
     5 import android.view.MenuItem;
     6 import android.view.View;
     7 
     8 public class MainActivity extends ActionBarActivity {
     9     int number=38;
    10     @Override
    11     protected void onCreate(Bundle savedInstanceState) {
    12         super.onCreate(savedInstanceState);
    13         setContentView(R.layout.activity_main);
    14     }
    15     
    16     public void doButton(View v) {
    17         Intent intent=new Intent();
    18         switch (v.getId()) {
    19         case R.id.button1:    
    20             intent.setAction("com.robin.testservice2.action");
    21             intent.putExtra("number", number);
    22             startService(intent);//启动服务
    23             number++;
    24             break;
    25         
    26         case R.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 import android.app.Service;
     2 import android.content.Intent;
     3 import android.media.MediaPlayer;
     4 import android.os.IBinder;
     5 import android.util.Log;
     6 
     7 public class MyService extends Service{
     8     protected static final String TAG = "robin debug";
     9     MediaPlayer mp;
    10     Thread printThread;
    11     int cnt=-1;
    12     boolean active=false;
    13     @Override
    14     public IBinder onBind(Intent intent) {
    15         return null;
    16     }
    17     
    18     @Override
    19     public void onCreate() {
    20         Log.e(TAG,"service create");
    21         super.onCreate();
    22     }
    23     
    24     @Override
    25     public int onStartCommand(Intent intent, int flags, int startId) {
    26         Log.e(TAG,"service start command");
    27         cnt=intent.getIntExtra("number", -1);
    28         active=true;
    29         printThread=new Thread(){
    30             @Override
    31             public void run() {
    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     @Override
    48     public void onDestroy() {
    49         active=false;
    50         super.onDestroy();
    51         Log.e(TAG,"service destroy");
    52     }
    53 }

     布局文件

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent" >
     5 
     6     <TextView
     7         android:id="@+id/textView1"
     8         android:layout_width="wrap_content"
     9         android:layout_height="wrap_content"
    10         android:text="@string/hello_world" />
    11 
    12     <Button
    13         android:id="@+id/button1"
    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     <Button
    24         android:id="@+id/button2"
    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 </RelativeLayout>

    以上的操作过程为,在Activity界面点击启动服务(startService(intent);)--->在MyService 中会执行

     使用方法二:绑定服务

    例子:Service与Activity之间进行通信

    先来看看方法之间的调用顺序/过程:

    上图中的代码:

    ICount.java 类:

    1 package com.robin.testservice3;
    2 
    3 
    4 public interface ICount { //描述需要的行为(功能)
    5     public int getCount();
    6     public void setCount(int cnt);
    7 }

    MainActivity.java

     1 package com.robin.testservice3;
     2 
     3 import android.content.ComponentName;
     4 import android.content.Intent;
     5 import android.content.ServiceConnection;
     6 import android.os.Bundle;
     7 import android.os.IBinder;
     8 import android.support.v7.app.ActionBarActivity;
     9 import android.view.Menu;
    10 import android.view.MenuItem;
    11 import android.view.View;
    12 import android.widget.TextView;
    13 
    14 public class MainActivity extends ActionBarActivity {
    15     private ICount count;
    16     private class MyConn implements ServiceConnection{
    17 
    18         @Override
    19         public void onServiceConnected(ComponentName name, IBinder binder) {
    20             count=(ICount) binder;
    21         }
    22 
    23         @Override
    24         public void onServiceDisconnected(ComponentName name) {
    25             count=null;
    26         }    
    27     }
    28     MyConn conn=new MyConn();
    29     TextView txt;
    30     @Override
    31     protected void onCreate(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     @Override
    40     public boolean onCreateOptionsMenu(Menu menu) {
    41         getMenuInflater().inflate(R.menu.main, menu);
    42         return true;
    43     }
    44 
    45     @Override
    46     public boolean onOptionsItemSelected(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 void doButton(View view ){
    55         switch (view.getId()) {
    56         case R.id.button1:
    57             txt.setText("来自service子线程的计数值:"+count.getCount());
    58             break;
    59         case R.id.button2:
    60             count.setCount(1000);    
    61             break;
    62         default:
    63             break;
    64         }
    65     }
    66     @Override
    67     protected void onDestroy() {
    68         unbindService(conn);
    69         super.onDestroy();
    70     }    
    71 }

    MyService.java

     1 package com.robin.testservice3;
     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     protected static final String TAG = "robin debug";
    11     private boolean active=false;
    12     private int cnt=0;
    13     private class MyBinder extends Binder implements ICount{
    14 
    15         @Override
    16         public int getCount() {
    17             return cnt;
    18         }
    19         @Override
    20         public void setCount(int cnt) {
    21             MyService.this.cnt=cnt;
    22         }
    23     }
    24     MyBinder binder=new MyBinder();
    25     
    26     @Override
    27     public IBinder onBind(Intent intent) {
    28         return binder;
    29     }
    30     
    31     @Override
    32     public void onCreate() {
    33         new Thread(new Runnable() {
    34             
    35             @Override
    36             public void run() {
    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     @Override
    53     public void onDestroy() {
    54         Log.e(TAG,"service call onDestroy");
    55         active=false;
    56         super.onDestroy();
    57     }
    58 }

    布局文件:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     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     <TextView
     9         android:layout_width="wrap_content"
    10         android:layout_height="wrap_content"
    11         android:text="测试绑定使用service" />
    12 
    13     <Button
    14         android:id="@+id/button1"
    15         android:layout_width="wrap_content"
    16         android:layout_height="wrap_content"
    17         android:text="读service端子线程的计数值"
    18         android:onClick="doButton"/>
    19 
    20     <Button
    21         android:id="@+id/button2"
    22         android:layout_width="wrap_content"
    23         android:layout_height="wrap_content"
    24         android:text="修改service端子线程的计数值" 
    25         android:onClick="doButton"/>
    26 
    27     <TextView
    28         android:id="@+id/result"
    29         android:layout_width="wrap_content"
    30         android:layout_height="wrap_content"
    31         android:text="TextView" />
    32 
    33 </LinearLayout>

  • 相关阅读:
    【转】Oracle中的decode在mysql中的等价实现
    Perhaps you are running on a JRE rather than a JDK
    iisapp -a命令出现 :此脚本不能与WScript工作
    HDU 6070 线段树
    HDU 1853 MCMF
    Codeforces 7C 扩展欧几里得
    HDU 5675 智慧数
    Lucas 大组合数
    bzoj 2179 FFT
    POJ 1155 树形背包
  • 原文地址:https://www.cnblogs.com/huaqing-wkc/p/4915352.html
Copyright © 2020-2023  润新知