Android10

来源:互联网 发布:php程序员简历项目经验 编辑:程序博客网 时间:2024/06/05 21:52

Android10

需求_调用服务的方法

在Activity里面直接调用Service里面的方法,直接调用时行不通的.
Activity和Service 是Context的子类,不能被new,是系统框架得到的.

绑定服务调用服务方法的原理

在服务里面创建内部类,间接的去调用服务里面的方法

  1. 绑定服务,得到中间人的对象, onBind()方法[MyBinder对象]
  2. MyBinder对象,就是服务内部类的对象(中间人的对象)
  3. 可以拿中间人的对象,调用中间人内部类的方法
  4. 而内部类的方法,可以去调用外部类的方法
  5. 间接的调用到了,外部类方法,服务里面的方法数据了

服务内部代码的编写

public class TestService extends Service {    /**     * 服务内部的中间人     */    public class MyBinder extends Binder {        /**         * 中间人帮忙简介的调用服务的方法.         * @param name            姓名         * @param money           钱         */        public void callMethodInService(String name, int money) {            if (money > 200) {                methodInService(name);            } else {                Toast.makeText(TestService.this, "这点钱不够用,我们要按照制度办事", 0).show();            }           }    }    // 在服务成功绑定的时候 返回服务中的代理人(中间人)    @Override    public IBinder onBind(Intent intent) {                  return new MyBinder();    }    @Override    public void onCreate() {        System.out.println("服务被创建了..");        super.onCreate();    }    @Override    public void onDestroy() {        System.out.println("服务被销毁了..");        super.onDestroy();    }    /**     * 服务内部的方法,帮助你办暂住证.     * @param name         姓名     */    public void methodInService(String name) {        Toast.makeText(this, name + "你的暂住证办好了...", 0).show();    }}

绑定服务调用服务方法

/** * 代理人 */private MyBinder myBinder;/** * 绑定服务获取中间人 */public void bind(View view) {    Intent intent = new Intent(this, TestService.class);    // conn 通讯频道. BIND_AUTO_CREATE如果服务不存在,会把服务创建出来.    bindService(intent, new MyConn(), BIND_AUTO_CREATE);}private class MyConn implements ServiceConnection {    // 当服务被成功连接的时候调用的方法    @Override    public void onServiceConnected(ComponentName name, IBinder service) {           myBinder = (MyBinder) service;    }    // 当服务失去连接的时候调用的方法.    @Override    public void onServiceDisconnected(ComponentName name) {    }   }/** * 通过中间人调用服务里面的方法 */public void call(View view) {        myBinder.callMethodInService("小XX", 250);    }}

绑定服务调用方法的回顾

服务端

public IBinder onBind(Intent intent) {    return new MyBinder();}    public class MyBinder extends Binder{    //自定义一个方法调用methodInService    public void CallMethodInService(String name , int money){        if (money >100) {            methodInService(name);        }else{            Toast.makeText(TestService.this, name + "钱太少了,办不了暂住证", 0).show();        }    }}

Activity端

-----------------------------------------    Intent intent = new Intent(this, TestService.class);    bindService(intent, new MyConn(), BIND_AUTO_CREATE);    public class MyConn implements ServiceConnection{    @Override    public void onServiceConnected(ComponentName name, IBinder service) {                   myBinder = (MyBinder) service;    }       }public void call(View view){    myBinder.CallMethodInService("sam", 10);}

通过接口隐藏代码内部实现的细节

public interface IService {    public void callMethodInService(String name,int money);}//private 和  implements IService{private class MyBinder extends Binder implements IService{    public void callMethodInService(String name, int money) {        if (money > 200) {            methodInService(name);        }else{            Toast.makeText(TestService.this, "这点钱不够用,我们要按照制度办事", 0).show();        }    }    public void 洗桑拿(){        Toast.makeText(TestService.this, "走,一起去洗桑拿吧...", 0).show();    }    public void 打麻将(){        Toast.makeText(TestService.this, "走,一起去打麻将吧...", 0).show();    }}-------------------------------------------------------private IService myBinder;private class MyConn implements ServiceConnection{    //当服务被成功连接的时候调用的方法    @Override    public void onServiceConnected(ComponentName name, IBinder service) {                        myBinder = (IService) service;    }    //当服务失去连接的时候调用的方法.    @Override    public void onServiceDisconnected(ComponentName name) {    }}public void call(View view){                 myBinder.callMethodInService("XXX", 250);}

绑定服务的生命周期

  • 绑定的方式开启服务,如果服务不存在,先执行onCreate在执行onbind
  • 服务的onstart和onstartcommand方法不会被执行
  • 解除绑定服务,先执行onunbind在执行ondetroy
  • 多次绑定服务,服务只会被创建一次,oncreate方法只会被执行一次
  • 多次绑定服务,onBind方法不会被重复调用
  • 在实际开发的时候,如果需要调用服务的方法,就绑定服务,只能绑定一次
  • 服务只可以被解绑一次,如果用同一个conn对象多次解绑,服务和抛出异常

两种开启服务方式比较

  • start的方式开启服务器

    服务一旦开启,长期后台运行,服务和开启者(Activity)没有任何的关系,开启者退出了,服务还是继续在后台长期运行,开启者(Activity)不可以调用服务里面的方法,在系统设置界面可以观察到

  • bind的方式开启服务

    不求同时生,但求同时死,如果开启者(Activity)退出了,服务也会跟者挂掉,
    开启者(Activity)可以间接的利用中间人调用服务里面的方法.在系统设置界面看不到的

服务如果被开启同时被绑定,服务就停不掉了.必须解除绑定才可以停止服务

混合调用服务的生命周期

  • 为了保证服务又能长期后台运行,又能调用到服务里面的方法
  • 采用混合的方式开启服务

按照步骤编写代码:

  1. start的方式开启服务(保证服务长期后台运行)
  2. bind的方式绑定服务(调用服务的方法)
  3. unbind的方式解除绑定服务
  4. stop的方式停止服务

本地服务和远程服务

  • 进程

    操作系统分配的独立的内存空间

  • IPC

    inter process communication 进程间通讯

  • aidl

    android interface definition language 安卓接口定义语言

aidl的编写步骤

  1. 跟本地服务的代码是一样
  2. 远程服务的接口的定义文件.java—>.aidl
  3. 把接口定义文件的访问修饰符全部删除 public private
  4. 原来代理人MyBinder extend Binder implement IService —>:extend IService.Stub
  5. 先把远程服务.AIDL文件拷贝到本地应用程序的工程目录里面,包名一致
  6. IService = IService.Stub.asInterface(service);得到远程服务的代理对象
  7. 通过代理对象调用远程服务的方法

绑定远程服务的应用场景

  1. 捕鱼游戏
  2. 支付宝

    bindService(intent, conn, BIND_AUTO_CREATE);iService = IService.Stub.asInterface(service);

支付宝安全支付案例

private class MyBinder extends IAlipayService.Stub{    @Override    public int callSafePay(String username, String password, float money) {        return safePay(username, password, money);    }}public int safePay(String username ,String password , float money){    if ("zhangsan".equals(username) && "123".equals(password)) {        if (money < 500) {//余额只有500元            return 200;        } else {            return 250;        }    } else {        return 404;    }}    <service android:name="com.xxx.newswork.service.AlipayService" ><!-- 远程项目调用服务 -->        <intent-filter >            <action android:name="com.xxx.alipay"/>        </intent-filter>    </service>@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_alipay);    //得到远程服务的代理人iAlipayService    Intent intent = new Intent();    intent.setAction("com.heima.alipay");    bindService(intent, new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            iAlipayService = IAlipayService.Stub.asInterface(service);        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    }, BIND_AUTO_CREATE);       }public void buyBall(View view){    //买炮弹    try {        int result = iAlipayService.callSafePay("zhangsan", "123", 800);//买个100元的炮弹        switch (result) {        case 200:            Toast.makeText(this, "支付成功", 0).show();            break;        case 250:            Toast.makeText(this, "卡上余额不足", 0).show();            break;        case 404:            Toast.makeText(this, "账号或者密码不正确", 0).show();                            break;        }               } catch (RemoteException e) {                   e.printStackTrace();    }       }

系统服务

  • 普通的服务(startService) ,activity想去调用服务的方法
  • 绑定的服务(bindService),一个应用程序需要调用另一个应用程序的服务
  • 远程的服务AIDL,系统服务对象 = context.getSystemService(系统服务)
  • 系统的服务

利用系统服务监听通话的状态

private class MyPhoneListener extends PhoneStateListener {    @Override    public void onCallStateChanged(int state, String incomingNumber) {        super.onCallStateChanged(state, incomingNumber);        switch (state) {        case TelephonyManager.CALL_STATE_IDLE: // 空闲状态,代表当前没有电话            if (mRecorder != null) {                System.out.println("停止录音");                stopRecording();            }            break;        case TelephonyManager.CALL_STATE_RINGING:// 响铃状态            break;        case TelephonyManager.CALL_STATE_OFFHOOK:// 通话状态            System.out.println("通话状态,开启录音机,录音.");            startRecording();            break;        }    }

通话录音

    /**     * 开始录音     */    private void startRecording() {        mRecorder = new MediaRecorder();        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 从麦克风录音        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);        mRecorder.setOutputFile("/mnt/sdcard/" + SystemClock.uptimeMillis()                + ".3gp");        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 手机的一种音频编码方式        try {            mRecorder.prepare();        } catch (Exception e) {            System.out.println("prepare() failed");        }        mRecorder.start();    }    /**     * 停止录音     */    private void stopRecording() {        mRecorder.stop();        mRecorder.release();        mRecorder = null;    }
0 0
原创粉丝点击