1.Service是Android四大组件之一,下面对Service进行一个简单的介绍,什么生命周期一些基础那些就直接跳过了

1.直接启动(startService) 2.绑定启动(bindService)。

1)具体在什么情况下用直接启动还是用绑定启动呢?

  如果你只是想要启动一个后台服务长期进行某项任务那么使用 startService 便可以了。如果你想要与正在运行的 Service 取得联系,那么有两种方法,一种是使用 broadcast ,另外是使用 bindService ,前者的缺点是如果交流较为频繁,容易造成性能上的问题,并且 BroadcastReceiver 本身执行代码的时间是很短的(也许执行到一半,后面的代码便不会执行),而后者则没有这些问题,因此我们肯定选择bindService(这个时候你便同时在使用 startService 和 bindService 了,这在 Activity 中更新 Service 的某些运行状态是相当有用的)。另外如果你的服务只是公开一个远程接口,供连接上的客服端(android 的 Service 是C/S架构)远程调用执行方法。这个时候你可以不让服务一开始就运行,而只用 bindService ,这样在第一次 bindService 的时候才会创建服务的实例运行它,这会节约很多系统资源,特别是如果你的服务是Remote Service,那么该效果会越明显(当然在 Service 创建的时候会花去一定时间,你应当注意到这点)。

2.Activity和Service通信方式一

  1)采用IBinder来进行通信,IBinder是Android专门用来进程通讯的。

别忘了对Service在AndroidManifest.xml进行注册)

  Service:(这里应该将MyBinder中的方法全部定义在接口里面,来继承接口实现)

1 public class MyService extends Service {
 2 
 3     @Override
 4     public IBinder onBind(Intent intent) {
 5         // intent获取从Activity传来的数据
 6         // 别忘了要返回定义binder实例, 如果返回就不能建立连接
 7         return new MyBinder();
 8     }
 9 
10     public class MyBinder extends Binder {
11 
12         // 加法
13         public int add(int a, int b) {
14             return a + b;
15         }
16 
17         public MyService getService() {
18             return MyService.this;
19         }
20 
21     }
22 
23     @Override
24     public void onCreate() {
25         super.onCreate();
26     }
27 
28     @Override
29     public void onDestroy() {
30         super.onDestroy();
31     }
32 
33 }

  Activity:

1 public class MainActivity extends Activity {
 2 
 3     private MyService.MyBinder binder;
 4     ServiceConnection connection;
 5 
 6     @Override
 7     protected void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.activity_main);
10 
11         connection = new ServiceConnection() {
12 
13             @Override
14             public void onServiceDisconnected(ComponentName name) {
15 
16             }
17 
18             @Override
19             public void onServiceConnected(ComponentName name, IBinder service) {
20                 // 获取被绑定service中的binder
21                 binder = (MyService.MyBinder) service;
22 
23                 System.out.println("从service返回来的数据->" + binder.add(5, 3));
24 
25             }
26         };
27 
28         Intent intent = new Intent("android.intent.mysecondservice");
29         bindService(intent, connection, BIND_AUTO_CREATE);
30 
31     }
32 
33 }

最后打印出的结果:

  

  2)在Service中开启一个线程模拟网络下载,将下载量在MainActivity中动态的打印出来(这里的IAddCount 接口是为后面去掉Activity中的线程,这里占时没有用的)

  Service:

1 public class MyService extends Service {
 2     private int count;
 3     private ServiceBinder binder;
 4     private boolean isGoOn = true;
 5     private IAddCount addCount;
 6 
 7     public interface IAddCount {
 8         public void showCount(int count);
 9 
10     }
11 
12     @Override
13     public IBinder onBind(Intent intent) {
14         System.out.println("从activity传过来的数据是-->>"
15                 + intent.getStringExtra("data"));
16 
17         return binder;
18     }
19 
20     public void setIAddCount(IAddCount addCount) {
21         this.addCount = addCount;
22     }
23 
24     public class ServiceBinder extends Binder {
25 
26         public int getCount() {
27             return count;
28         }
29 
30         public MyService getService() {
31             return MyService.this;
32         }
33 
34     }
35 
36     @Override
37     public void onCreate() {
38         super.onCreate();
39         System.out.println("MyService---onCreate()");
40         binder = new ServiceBinder();
41 
42         new Thread(new Runnable() {
43 
44             @Override
45             public void run() {
46 
47                 while (isGoOn) {
48                     try {
49                         Thread.sleep(1000);
50                         count++;
51                         if (count == 5) {
52                             isGoOn = false;
53                         }
54                     } catch (InterruptedException e) {
55                         e.printStackTrace();
56                     }
57 
58                 }
59 
60             }
61         }).start();
62 
63     }
64 
65     @Override
66     public void onDestroy() {
67         super.onDestroy();
68         System.out.println("MyService---onDestroy");
69 
70     }
71 
72 }

  MainActivity:

  

1 public class MainActivity extends Activity {
 2 
 3     private MyService.MyBinder binder;
 4     ServiceConnection connection;
 5 
 6     @Override
 7     protected void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.activity_main);
10 
11         connection = new ServiceConnection() {
12 
13             @Override
14             public void onServiceDisconnected(ComponentName name) {
15 
16             }
17 
18             @Override
19             public void onServiceConnected(ComponentName name, IBinder service) {
20                 // 获取被绑定service中的binder
21                 binder = (MyService.MyBinder) service;
22 
23                 System.out.println("从service返回来的数据->" + binder.add(5, 3));
24 
25             }
26         };
27 
28         Intent intent = new Intent("android.intent.mysecondservice");
29         bindService(intent, connection, BIND_AUTO_CREATE);
30 
31     }
32 
33 }

打印出的结果是:

   

3)这里在获取Service的数据的时候,是在Activity中开了一个线程与Service中的线程去对应,然后动态的去提取数据的,其实可以采用接口回调的方法来实现,不用去在开线程的

  Service:

1 public class MyService extends Service {
 2     private int count;
 3     private ServiceBinder binder;
 4     private boolean isGoOn = true;
 5     private IAddCount addCount;
 6 
 7     public interface IAddCount {
 8         public void showCount(int count);
 9 
10     }
11 
12     @Override
13     public IBinder onBind(Intent intent) {
14         System.out.println("从activity传过来的数据是-->>"
15                 + intent.getStringExtra("data"));
16 
17         return binder;
18     }
19 
20     public void setIAddCount(IAddCount addCount) {
21         this.addCount = addCount;
22     }
23 
24     public class ServiceBinder extends Binder {
25 
26         public int getCount() {
27             return count;
28         }
29 
30         public MyService getService() {
31             return MyService.this;
32         }
33 
34     }
35 
36     @Override
37     public void onCreate() {
38         super.onCreate();
39         System.out.println("MyService---onCreate()");
40         binder = new ServiceBinder();
41 
42         new Thread(new Runnable() {
43 
44             @Override
45             public void run() {
46 
47                 while (isGoOn) {
48                     try {
49                         Thread.sleep(1000);
50                         count++;
51                         if (count == 5) {
52                             isGoOn = false;
53                         }
54                     } catch (InterruptedException e) {
55                         e.printStackTrace();
56                     }
57 
58                 }
59 
60             }
61         }).start();
62 
63     }
64 
65     @Override
66     public void onDestroy() {
67         super.onDestroy();
68         System.out.println("MyService---onDestroy");
69 
70     }
71 
72 }

 

  MainActivity:

  

1 public class SecondActivity extends Activity implements OnClickListener {
 2 
 3     private Button btn;
 4     private int count;
 5     MyService.ServiceBinder binder;
 6     private boolean isBack = true;
 7     private MyService myService;
 8 
 9     @Override
10     protected void onCreate(Bundle savedInstanceState) {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.activity_second);
13         btn = (Button) findViewById(R.id.btn222);
14         btn.setOnClickListener(this);
15     }
16 
17     @Override
18     public void onClick(View v) {
19 
20         switch (v.getId()) {
21         case R.id.btn222:
22 
23             Intent intent = new Intent("android.intent.myservice");
24             intent.putExtra("data", "我是从activity传过来的数据");
25             ServiceConnection sercon = new ServiceConnection() {
26 
27                 @Override
28                 public void onServiceDisconnected(ComponentName name) {
29 
30                 }
31 
32                 @Override
33                 public void onServiceConnected(ComponentName name,
34                         IBinder service) {
35                     binder = (MyService.ServiceBinder) service;
36                     myService = binder.getService();
37                     // 实例化接口
38                     myService.setIAddCount(new IAddCount() {
39                         // ************************************//
40                         // 接口回调
41                         @Override
42                         public void showCount(int count) {
43                             System.out.println("接口回调返回的数据是-->>" + count);
44                         }
45                     });
46                 }
47             };
48             bindService(intent, sercon, BIND_AUTO_CREATE);
49             System.out.println("输出的数据是-->>" + count);
50 
51             // new Thread() {
52             // @Override
53             // public void run() {
54             // try {
55             // while (isBack) {
56             // Thread.sleep(1000);
57             // count = binder.getCount();
58             // if (count == 5) {
59             // isBack = false;
60             // }
61             //
62             // Message msg = myHandler.obtainMessage();
63             // msg.arg1 = count;
64             // myHandler.sendMessage(msg);
65             // }
66             //
67             // } catch (InterruptedException e) {
68             // e.printStackTrace();
69             // }
70             //
71             // }
72             //
73             // }.start();
74 
75             break;
76         }
77 
78     }
79 
80     Handler myHandler = new Handler() {
81         public void handleMessage(android.os.Message msg) {
82 
83             System.out.println("在activity中获取到的数据是->" + msg.arg1);
84 
85         };
86 
87     };
88 
89 }

运行后的效果和上图一样的

通过broadcast(广播)的形式

   在Activity中动态注册一个广播接收器,然后service将数据广播给Activity中的接收器即可

  

1 public class MainActivity extends Activity {  
 2     private ProgressBar mProgressBar;  
 3     private Intent mIntent;  
 4     private MsgReceiver msgReceiver;  
 5       
 6   
 7     @Override  
 8     protected void onCreate(Bundle savedInstanceState) {  
 9         super.onCreate(savedInstanceState);  
10         setContentView(R.layout.activity_main);  
11           
12         //动态注册广播接收器  
13         msgReceiver = new MsgReceiver();  
14         IntentFilter intentFilter = new IntentFilter();  
15         intentFilter.addAction("com.example.communication.RECEIVER");  
16         registerReceiver(msgReceiver, intentFilter);  
17           
18           
19         mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);  
20         Button mButton = (Button) findViewById(R.id.button1);  
21         mButton.setOnClickListener(new OnClickListener() {  
22               
23             @Override  
24             public void onClick(View v) {  
25                 //启动服务  
26                 mIntent = new Intent("com.example.communication.MSG_ACTION");  
27                 startService(mIntent);  
28             }  
29         });  
30           
31     }  
32   
33       
34     @Override  
35     protected void onDestroy() {  
36         //停止服务  
37         stopService(mIntent);  
38         //注销广播  
39         unregisterReceiver(msgReceiver);  
40         super.onDestroy();  
41     }  
42   
43   
44     /** 
45      * 广播接收器 
46      * @author len 
47      * 
48      */  
49     public class MsgReceiver extends BroadcastReceiver{  
50   
51         @Override  
52         public void onReceive(Context context, Intent intent) {  
53             //拿到进度,更新UI  
54             int progress = intent.getIntExtra("progress", 0);  
55             mProgressBar.setProgress(progress);  
56         }  
57           
58     }  
59   
60 }

 

  Service :

  

1 public class MsgService extends Service {  
 2     /** 
 3      * 进度条的最大值 
 4      */  
 5     public static final int MAX_PROGRESS = 100;  
 6     /** 
 7      * 进度条的进度值 
 8      */  
 9     private int progress = 0;  
10       
11     private Intent intent = new Intent("com.example.communication.RECEIVER");  
12       
13   
14     /** 
15      * 模拟下载任务,每秒钟更新一次 
16      */  
17     public void startDownLoad(){  
18         new Thread(new Runnable() {  
19               
20             @Override  
21             public void run() {  
22                 while(progress < MAX_PROGRESS){  
23                     progress += 5;  
24                       
25                     //发送Action为com.example.communication.RECEIVER的广播  
26                     intent.putExtra("progress", progress);  
27                     sendBroadcast(intent);  
28                       
29                     try {  
30                         Thread.sleep(1000);  
31                     } catch (InterruptedException e) {  
32                         e.printStackTrace();  
33                     }  
34                       
35                 }  
36             }  
37         }).start();  
38     }  
39   
40       
41   
42     @Override  
43     public int onStartCommand(Intent intent, int flags, int startId) {  
44         startDownLoad();  
45         return super.onStartCommand(intent, flags, startId);  
46     }  
47   
48   
49   
50     @Override  
51     public IBinder onBind(Intent intent) {  
52         return null;  
53     }

 

 

Activity调用 bindService (Intent service, ServiceConnection conn, int flags)方法,得到Service对象的一个引用,这样Activity可以直接调用到Service中的方法,如果要主动通知Activity,我 们可以利用回调方法

 Service向Activity发送消息,可以使用广播,当然Activity要注册相应的接收器。比如Service要向多个Activity发送同样的消息的话,用这种方法就更好

  

参考地址:

    

 

关于怎样让服务不被杀死

  这个倒是有点流氓软件的意思,但有些特定情况还是需要服务能保持开启不被杀死,当然这样做我还是在程序里添加了关闭服务的按钮,也就是开启了就杀不死,除非在软件里关闭。

服务不被杀死分3种来讨论
1.系统根据资源分配情况杀死服务
2.用户通过settings->Apps->Running->Stop方式杀死服务
3.用户通过settings->Apps->Downloaded->Force Stop方式杀死服务

第一种情况:
  用户不干预,完全靠系统来控制,办法有很多。比如onStartCommand()方法的返回值设为START_STICKY,服务就会在资源紧张的时候被杀掉,然后在资源足够的时候再恢复。当然也可设置为前台服务,使其有高的优先级,在资源紧张的时候也不会被杀掉。

第二种情况:
  用户干预,主动杀掉运行中的服务。这个过程杀死服务会通过服务的生命周期,也就是会调用onDestory()方法,这时候一个方案就是在onDestory()中发送广播开启自己。这样杀死服务后会立即启动。如下:

1 @Override
 2 public void onCreate() {
 3     // TODO Auto-generated method stub
 4     super.onCreate();
 5 
 6     mBR = new BroadcastReceiver() {
 7         @Override
 8         public void onReceive(Context context, Intent intent) {
 9             // TODO Auto-generated method stub
10             Intent a = new Intent(ServiceA.this, ServiceA.class);
11             startService(a);
12         }
13     };
14     mIF = new IntentFilter();
15     mIF.addAction("listener");
16     registerReceiver(mBR, mIF);
17 }
18 
19 @Override
20 public void onDestroy() {
21     // TODO Auto-generated method stub
22     super.onDestroy();
23 
24     Intent intent = new Intent();
25     intent.setAction("listener");
26     sendBroadcast(intent);
27 
28     unregisterReceiver(mBR);
29 }

当然,从理论上来讲这个方案是可行的,实验一下也可以。但有些情况下,发送的广播在消息队列中排的靠后,就有可能服务还没接收到广播就销毁了(这是 我对实验结果的猜想,具体执行步骤暂时还不了解)。所以为了能让这个机制完美运行,可以开启两个服务,相互监听,相互启动。服务A监听B的广播来启动B, 服务B监听A的广播来启动A。经过实验,这个方案可行,并且用360杀掉后几秒后服务也还是能自启的。到这里再说一句,如果不是某些功能需要的服务,不建 议这么做,会降低用户体验。

第三种情况:
  强制关闭就没有办法。这个好像是从包的level去关的,并不走完整的生命周期。所以在服务里加代码是无法被调用的。处理这个情况的唯一方法是屏蔽掉force stopuninstall按钮,让其不可用。方法自己去找吧。当然有些手机自带的清理功能就是从这个地方清理的,比如华为的清理。所以第三种情况我也没有什么更好的办法了。