android 学习随笔十八(广播与服务 )

1、广播接收者注册

  • 清单文件注册(Android四大组件都要在清单文件中注册

 一旦应用部署,广播接收者就生效了,直到用户手动停止应用或者应用被删除

  • 广播接收者可以使用代码注册

 需要广播接收者运行时,使用代码注册,不需要时,可以使用代码解除注册
 特殊广播接收者,必须代码注册。电量改变、屏幕开关,必须使用代码注册

2、注册广播接收者

//创建广播接收者对象
receiver = new ScreenOnOffReceiver();
//通过IntentFilter对象指定广播接收者接收什么类型的广播
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);

//注册广播接收者
registerReceiver(receiver, filter);
* 解除注册广播接收者

unregisterReceiver(receiver);
* 解除注册之后,广播接收者将失去作用

 1 package com.itheima.register;
 2 
 3 import android.content.BroadcastReceiver;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 
 7 public class ScreenOnOFFReceiver extends BroadcastReceiver {
 8 
 9     @Override
10     public void onReceive(Context context, Intent intent) {
11         
12         String action = intent.getAction();
13         if(Intent.ACTION_SCREEN_ON.equals(action)){
14             System.out.println("屏幕开啦啦");
15         }
16         else if(Intent.ACTION_SCREEN_OFF.equals(action)){
17             System.out.println("屏幕关哇哇");
18         }
19 
20     }
21 
22 }
View Code
 1 package com.itheima.register;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.content.IntentFilter;
 6 import android.os.IBinder;
 7 
 8 public class RegisterService extends Service {
 9 
10     private ScreenOnOFFReceiver receiver;
11 
12     @Override
13     public IBinder onBind(Intent intent) {
14         // TODO Auto-generated method stub
15         return null;
16     }
17 
18     @Override
19     public void onCreate() {
20         super.onCreate();
21         //1.创建广播接收者对象
22         receiver = new ScreenOnOFFReceiver();
23         //2.创建意图过滤器对象
24         IntentFilter filter = new IntentFilter();
25         //指定接收什么广播
26         filter.addAction(Intent.ACTION_SCREEN_OFF);
27         filter.addAction(Intent.ACTION_SCREEN_ON);
28         //3.注册广播接收者
29         registerReceiver(receiver, filter);
30         
31     }
32     
33     @Override
34     public void onDestroy() {
35         super.onDestroy();
36         //反注册广播接收者
37         unregisterReceiver(receiver);
38     }
39     
40 }
View Code
 1 package com.itheima.register;
 2 
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.content.Intent;
 6 import android.view.Menu;
 7 import android.view.View;
 8 
 9 public class MainActivity extends Activity {
10 
11     @Override
12     protected void onCreate(Bundle savedInstanceState) {
13         super.onCreate(savedInstanceState);
14         setContentView(R.layout.activity_main);
15     }
16 
17 
18     public void start(View v){
19         Intent intent = new Intent(this, RegisterService.class);
20         startService(intent);
21     }
22     public void stop(View v){
23         Intent intent = new Intent(this, RegisterService.class);
24         stopService(intent);
25     }
26     
27 }
View Code

 服务注册广播

3、服务的分类

  • 本地服务:服务和启动它的组件在同一个进程
  • 远程服务:服务和启动它的组件不在同一个进程
  • 远程服务只能隐式启动,类似隐式启动Activity,在清单文件中配置Service标签时,必须配置intent-filter子节点,并指定action子节点

远程服务

 1 package com.itheima.remoteservice;
 2 
 3 import com.itheima.remoteservice.PublicBusiness.Stub;
 4 
 5 import android.app.Service;
 6 import android.content.Intent;
 7 import android.os.Binder;
 8 import android.os.IBinder;
 9 
10 public class RemoteService extends Service{
11 
12     @Override
13     public IBinder onBind(Intent intent) {
14         System.out.println("绑定");
15         return new FengMiShu();
16     }
17 
18     class FengMiShu extends Stub{
19 
20         @Override
21         public void qianXian() {
22             // TODO Auto-generated method stub
23             remoteBanZheng();
24         }
25         
26     }
27     
28     @Override
29     public boolean onUnbind(Intent intent) {
30         System.out.println("解绑");
31         return super.onUnbind(intent);
32     }
33     
34     @Override
35     public void onCreate() {
36         System.out.println("创建");
37         super.onCreate();
38     }
39     
40     @Override
41     public int onStartCommand(Intent intent, int flags, int startId) {
42         System.out.println("开始");
43         return super.onStartCommand(intent, flags, startId);
44     }
45     
46     @Override
47     public void onDestroy() {
48         System.out.println("摧毁");
49         super.onDestroy();
50     }
51     
52     public void remoteBanZheng(){
53         System.out.println("苗领导在国外远程办证");
54     }
55 
56 }
View Code
 1 package com.itheima.remoteservice;
 2 
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.view.Menu;
 6 
 7 public class MainActivity extends Activity {
 8 
 9     @Override
10     protected void onCreate(Bundle savedInstanceState) {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.activity_main);
13     }
14 
15 
16     @Override
17     public boolean onCreateOptionsMenu(Menu menu) {
18         // Inflate the menu; this adds items to the action bar if it is present.
19         getMenuInflater().inflate(R.menu.main, menu);
20         return true;
21     }
22     
23 }
View Code
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.itheima.remoteservice"
 4     android:versionCode="1"
 5     android:versionName="1.0" >
 6 
 7     <uses-sdk
 8         android:minSdkVersion="8"
 9         android:targetSdkVersion="17" />
10 
11     <application
12         android:allowBackup="true"
13         android:icon="@drawable/ic_launcher"
14         android:label="@string/app_name"
15         android:theme="@style/AppTheme" >
16         <activity
17             android:name="com.itheima.remoteservice.MainActivity"
18             android:label="@string/app_name" >
19             <intent-filter>
20                 <action android:name="android.intent.action.MAIN" />
21 
22                 <category android:name="android.intent.category.LAUNCHER" />
23             </intent-filter>
24         </activity>
25         <service android:name="com.itheima.remoteservice.RemoteService">
26             <intent-filter >
27                 <action android:name="com.itheima.remote"/>
28             </intent-filter>
29         </service>
30     </application>
31 
32 </manifest>
View Code

调用远程服务操作

package com.itheima.runremoteservice;

public interface PublicBusiness {

    void qianXian();
}
 1 package com.itheima.runremoteservice;
 2 
 3 import android.os.Bundle;
 4 import android.os.IBinder;
 5 import android.app.Activity;
 6 import android.content.ComponentName;
 7 import android.content.Intent;
 8 import android.content.ServiceConnection;
 9 import android.view.Menu;
10 import android.view.View;
11 
12 public class MainActivity extends Activity {
13 
14     public PublicBusiness pb;
15     private MyConn conn;
16 
17     @Override
18     protected void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         setContentView(R.layout.activity_main);
21         
22         conn = new MyConn();
23     }
24 
25 
26     public void start(View v){
27         Intent intent = new Intent();
28         intent.setAction("com.itheima.remote");
29         startService(intent);
30     }
31     public void stop(View v){
32         Intent intent = new Intent();
33         intent.setAction("com.itheima.remote");
34         stopService(intent);
35     }
36     public void bind(View v){
37         Intent intent = new Intent();
38         intent.setAction("com.itheima.remote");
39         bindService(intent, conn, BIND_AUTO_CREATE);
40     }
41     
42     public void unbind(View v){
43         unbindService(conn);
44     }
45     class MyConn implements ServiceConnection{
46 
47         @Override
48         public void onServiceConnected(ComponentName name, IBinder service) {
49             pb = (PublicBusiness) service;
50             
51         }
52 
53         @Override
54         public void onServiceDisconnected(ComponentName name) {
55             // TODO Auto-generated method stub
56             
57         }
58         
59     }
60     
61     public void banZheng(View v){
62         pb.qianXian();
63     }
64 }
View Code

4、AIDL  Android interface definition language,在Android中用于进程间通讯

* 安卓接口定义语言
* 作用:跨进程通信
* 应用场景:远程服务中的中间人对象,其他应用是拿不到的,那么在通过绑定服务获取中间人对象时,就无法强制转换,使用aidl,就可以在其他应用中拿到中间人类所实现的接口

步骤

远程服务
1. 把接口文件的后缀名改成aidl(在gen目录下会根据aidl文件生成一个.java文件)
2. aidl文件中所有东西都是public的,不需要也不能自己定义访问修饰符
3. 中间人对象继承Stub,这个对象已经继承了Binder并实现了PublicBusiness接口(自定义接口)

启动调用远程服务
1. 把远程服务项目的aidl文件复制到启动调用远程服务项目(先创建一个和服务aidl所在包相同的包名),然后aidl所在的包名远程服务启动调用远程服务项目必须一致(在gen目录下会根据aidl文件生成一个.java文件)
2. 把启动调用远程服务项目获取到的中间人对象使用Stub.asInterface强转

public void onServiceConnected(ComponentName name, IBinder service) {
pb = Stub.asInterface(service);
}

 例:

  • 支付宝远程服务

1. 定义支付宝的服务,在服务中定义pay方法
2. 定义中间人对象,把pay方法抽取成接口
3. 把抽取出来的接口后缀名改成aidl
4. 中间人对象直接继承Stub对象
5. 注册这个支付宝服务,定义它的intent-Filter

  • 需要支付的应用

1. 把刚才定义好的aidl文件拷贝过来,注意aidl文件所在的包名必须跟原包名一致
2. 远程绑定支付宝的服务,通过onServiceConnected方法我们可以拿到中间人对象
3. 把中间人对象通过Stub.asInterface方法强转成定义了pay方法的接口
4. 调用中间人的pay方法

 1 package com.itheima.paybaby;
 2 
 3 import com.itheima.paybaby.PayInterface.Stub;
 4 
 5 import android.app.Service;
 6 import android.content.Intent;
 7 import android.os.IBinder;
 8 import android.os.RemoteException;
 9 
10 public class PayService extends Service {
11 
12     @Override
13     public IBinder onBind(Intent intent) {
14         // TODO Auto-generated method stub
15         return new PayController();
16     }
17 
18     class PayController extends Stub{
19 
20         @Override
21         public void pay() throws RemoteException {
22             PayService.this.pay();
23             
24         }
25         
26     }
27     
28     private void pay() {
29         System.out.println("检查支付环境");
30         System.out.println("加密账号密码");
31         System.out.println("上传账号密码");
32         System.out.println("完成支付");
33 
34     }
35 }
View Code
 1 package com.itheima.paybaby;
 2 
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.view.Menu;
 6 
 7 public class MainActivity extends Activity {
 8 
 9     @Override
10     protected void onCreate(Bundle savedInstanceState) {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.activity_main);
13     }
14 
15 
16     @Override
17     public boolean onCreateOptionsMenu(Menu menu) {
18         // Inflate the menu; this adds items to the action bar if it is present.
19         getMenuInflater().inflate(R.menu.main, menu);
20         return true;
21     }
22     
23 }
View Code

调用

 1 package com.itheima.naocangame;
 2 
 3 import com.itheima.paybaby.PayInterface;
 4 import com.itheima.paybaby.PayInterface.Stub;
 5 
 6 import android.os.Bundle;
 7 import android.os.IBinder;
 8 import android.os.RemoteException;
 9 import android.app.Activity;
10 import android.content.ComponentName;
11 import android.content.Intent;
12 import android.content.ServiceConnection;
13 import android.view.Menu;
14 import android.view.View;
15 
16 public class MainActivity extends Activity {
17 
18     PayInterface pi;
19     @Override
20     protected void onCreate(Bundle savedInstanceState) {
21         super.onCreate(savedInstanceState);
22         setContentView(R.layout.activity_main);
23         
24         //绑定远程服务
25         Intent intent = new Intent("com.itheima.babypay");
26         bindService(intent, new ServiceConnection() {
27             
28             @Override
29             public void onServiceDisconnected(ComponentName name) {
30                 // TODO Auto-generated method stub
31                 
32             }
33             
34             @Override
35             public void onServiceConnected(ComponentName name, IBinder service) {
36                 pi = Stub.asInterface(service);
37                 
38             }
39         }, BIND_AUTO_CREATE);
40         
41     }
42 
43 
44     public void click(View v){
45         try {
46             pi.pay();
47         } catch (RemoteException e) {
48             // TODO Auto-generated catch block
49             e.printStackTrace();
50         }
51     }
52     
53 }
View Code

 5、进程优先级

  • 五种前台进程

1. activity执行了onresume方法,获得焦点
2. 拥有一个跟正在与用户交互的activity绑定的服务
3. 拥有一个服务执行了startForeground()方法
4. 拥有一个正在执行onCreate()、onStart()或者onDestroy()方法中的任意一个的服务
5. 拥有一个正在执行onReceive方法的广播接收者

  • 两种可见进程

1. activity执行了onPause方法,失去焦点,但是可见
2. 拥有一个跟可见或前台activity绑定的服务

原文地址:https://www.cnblogs.com/ecollab/p/5912656.html