欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

黑马Android76期学习笔记01基础--day08--start/bind开启服务、电话录音,特别广播接收者,bindService/接口调用服务内方法,混合开启服务,进程间通讯,aidl应用场景

程序员文章站 2022-03-30 18:48:07
1.广播Broadcastreceiver...
1.进程的基本概念

1、android下四大组件都是运行在主线程中,他没有界面,在后台运行
2、Foreground process前台进程,优先级最高,相当于activity执行了onresume方法,用户正在交互
3、visible process可视进程,一直影响用户看得见的体验,相当于activity执行了onpause方法
4、service process服务进程,通过startService开启一个服务
5、backgroud process后台进程 相当于activity执行了onStop方法,界面不可见,但是activity并没有被销毁
6、empty process 空进程 ,不会维持任何组件运行,但会占用内存

2.start方式开启服务

需要在清单文件中注册
1、定义四大组件的方式是一样的
2、定义一个类继承Service
3、服务一旦被开启,就会在后台长期运行,知道用户手工停止

1、DemoService

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class DemoService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.d("TAG", "onCreate: --------");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("TAG", "onStartCommand: --------");

        return super.onStartCommand(intent, flags, startId);
    }
}

2、MainActivity

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void btnStratClick(View view){
        Intent intent=new Intent(this,DemoService.class);
        startService(intent);
        //stopService(intent);

    }
}

打印

2020-08-22 10:46:19.280 4264-4264/com.fengray.ex066 D/TAG: onCreate: --------
2020-08-22 10:46:19.281 4264-4264/com.fengray.ex066 D/TAG: onStartCommand: --------

2.电话监听案例

开启电话状态监听许可

**1、清单文件**
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fengray.ex067">
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".PhoneService">

        </service>
    </application>

</manifest>

2、PhoneService类

package com.fengray.ex067;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

import androidx.annotation.Nullable;

public class PhoneService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        //获得telephonemanager的实例
        @SuppressLint("ServiceCast")
        TelephonyManager telephonyManager=(TelephonyManager)getSystemService(TELECOM_SERVICE);

        //注册电话的监听
        telephonyManager.listen(new MyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    //定义类来监听电话的状态
    private class MyPhoneStateListener extends PhoneStateListener{
    //当电话设置状态发生改变时调用

        @Override
        public void onCallStateChanged(int state, String phoneNumber) {
            //判断一下电话的状态
            switch (state){
                case TelephonyManager.CALL_STATE_IDLE://空闲
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK://摘机
                    break;
                case TelephonyManager.CALL_STATE_RINGING://响铃
                    Log.d("TAG", "onCallStateChanged: 准备录音");
                    break;
            }
            super.onCallStateChanged(state, phoneNumber);
        }
    }
}

3、MainActivity

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    public void btnstart(View view){
        Intent intent=new Intent(this,PhoneService.class);
        startService(intent);
    }
}
3.电话录音

1、清单文件设置服务和广播以及各种权限(andorid6以后有新的要求,需要先询问)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fengray.ex067">
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".PhoneService">

        </service>
        <receiver android:name=".BootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

2、BootReceiver 类继承BroadcastReceiver

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //把服务开启
        Intent intent1=new Intent(context,PhoneService.class);
        context.startService(intent1);
    }
}

**3、PhoneService 类继承Service **

public class PhoneService extends Service {
    MediaRecorder recorder=null;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        //获得telephonemanager的实例
        @SuppressLint("ServiceCast")
        TelephonyManager telephonyManager=(TelephonyManager)getSystemService(TELECOM_SERVICE);

        //注册电话的监听
        telephonyManager.listen(new MyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    //定义类来监听电话的状态
    private class MyPhoneStateListener extends PhoneStateListener{
    //当电话设置状态发生改变时调用

        @Override
        public void onCallStateChanged(int state, String phoneNumber) {
            //判断一下电话的状态
            switch (state){
                case TelephonyManager.CALL_STATE_IDLE://空闲
                    if (recorder!=null){
                        //停止录音
                        recorder.stop();
                        recorder.reset();   // You can reuse the object by going back to setAudioSource() step
                        recorder.release(); // Now the object cannot be reused
                    }
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK://摘机
                    recorder.start();   // Recording is now started

                    break;
                case TelephonyManager.CALL_STATE_RINGING://响铃
                    //拿到媒体录音对象
                    recorder=new MediaRecorder();//创建recorder实例
                    //设置音频的来源
                    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    //设置输出格式
                    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                    //设置音频的编码方式
                    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                    //设置存放的路径
                    recorder.setOutputFile("/mnt/sdcard/luyin.3gp");
                    //准备录音
                    try {
                        recorder.prepare();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    break;
            }
            super.onCallStateChanged(state, phoneNumber);
        }
    }
}

**4、MainActivity类 **

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

}
4.注册特别的广播接受者(特别频繁的操作,如解锁屏)

1、写一个广播类,编写广播接收业务逻辑
2、写一个服务,用来注册广播接受者
3、在主类中的oncreate方法中开启服务
4、配置清单文件

1、ScreenReceiver 类

package com.fengray.ex068;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class ScreenReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //获得当前事件类型
        String action=intent.getAction();
        if ("android.intent.action.SCREEN_OFF".equals(action)){
            Log.d("TAG", "说明屏幕锁屏了");
        }else if ("android.intent.action.SCREEN_ON".equals(action)){
            Log.d("TAG", "说明屏幕解锁了 ");
        }
    }
}

2、ScreenService 类

package com.fengray.ex068;

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;

import androidx.annotation.Nullable;

public class ScreenService extends Service {
    ScreenReceiver screenReceiver;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        //在这里通过代码的方式来注册广播(因为是特殊的广播接收者)
        //创建screenReceiver实例
        screenReceiver=new ScreenReceiver();
        //创建IntentFilter实例,其目的是为了添加action
        IntentFilter intentFilter=new IntentFilter();
        //添加action
        intentFilter.addAction("android.intent.action.SCREEN_OFF");
        intentFilter.addAction("android.intent.action.SCREEN_ON");
        //动态接收广播接受者
        registerReceiver(screenReceiver,intentFilter);
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        unregisterReceiver(screenReceiver);
        super.onDestroy();
    }

}

3、MainActivity 主类

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建一个指向Service页面的intent,由于service*面,所以实际上就是做启动服务的准备
        Intent intent=new Intent(this,ScreenService.class);
        //开启服务
        startService(intent);
    }
}

4、清单文件
其实就是注册服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fengray.ex068">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".ScreenService">

        </service>
    </application>

</manifest>

打印:
2020-08-22 21:08:32.064 8665-8665/com.fengray.ex068 D/TAG: 说明屏幕锁屏了
2020-08-22 21:08:33.623 8665-8714/com.fengray.ex068 D/EGL_emulation: eglMakeCurrent: 0x7aabda840540: ver 3 1 (tinfo 0x7aabda80dba0)
2020-08-22 21:08:33.656 8665-8665/com.fengray.ex068 D/TAG: 说明屏幕解锁了
2020-08-22 21:08:37.711 8665-8714/com.fengray.ex068 D/EGL_emulation: eglMakeCurrent: 0x7aabda840540: ver 3 1 (tinfo 0x7aabda80dba0)
2020-08-22 21:08:37.798 8665-8665/com.fengray.ex068 D/TAG: 说明屏幕锁屏了
2020-08-22 21:08:39.963 8665-8665/com.fengray.ex068 D/TAG: 说明屏幕解锁了 、

5.通过bind添加服务

1、服务不能多次解绑
2、onbind方法返回null是,onServiceconnected方法是不执行的
3、通过bind方式开启服务,服务不能再设置页面找到,相当于一个隐形的服务
1、DemoService

public class DemoService extends Service {

    @Nullable
    @Override
    //当绑定服务的时候
    public IBinder onBind(Intent intent) {
        Log.d("TAG", "onBind: -------");
        return null;//返回null则表示这个方法不执行
    }

    @Override
    public void onCreate() {
        Log.d("TAG", "onCreate: ----");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.d("TAG", "onDestroyAndUnbindService: ----");
        super.onDestroy();
    }
}

2、MainActivity

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private Myconn conn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }
    //点击绑定服务按钮
    public void btnBindClick(View view){
        Intent intent=new Intent(this,DemoService.class);
        conn=new Myconn();
        //连接到DemoService这个服务
        bindService(intent,conn,BIND_AUTO_CREATE);

    }
    //点击解绑服务按钮
    public void btnUnbindClick(View view){
        unbindService(conn);

    }
    //点击启动服务按钮
    public void startClick(View view){
        Intent intent=new Intent(this,DemoService.class);
        startService(intent);
    }

    private class Myconn implements ServiceConnection{
        //当服务连接成功调用
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("TAG", "onServiceConnected: -----");

        }
        //当服务失去连接
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("TAG", "onServiceDisconnected: ----");

        }
    }
}

3、清单文件中注册一下服务

<service android:name=".DemoService"></service>
6.通过bindservice方式调用服务内部方法

1、在服务的内部定义一个被调用的方法
2、在服务的内部定义一个中间人对象(IBinder)
3、把定义的中间人对象在onBind方法中返回。
4、在mainactivity的oncreate方法里调用bindservice,其目的是为了获取我们定义的中间人对象
5、获取中间人对象
6、拿到中间人对象,通过中间人对象调用服务内容的方法
7,当activity销毁的时候,要解绑服务

1、清单文件里注册服务

<service android:name=".BanzhengService"></service>

2、BanzhengService 服务类

public class BanzhengService extends Service {
    @Nullable
    @Override
    //把自己定义的中间人对象返回
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }
    //办证方法
    public void banzheng(int money){
        if (money>1000){
            Toast.makeText(getApplicationContext(), "我是领导,把证给办了", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(getApplicationContext(), "这点钱,还想办事情吗", Toast.LENGTH_SHORT).show();
        }
    }

    //定义一个中间人对象(IBinder)
    public class MyBinder extends Binder{
        //调用服务里的方法
        public void callBanzheng(int money){
            banzheng(money);
        }
    }

}

3、MainActivity类

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private Myconn conn;
    BanzhengService.MyBinder myBinder;//自定义的中间人对象
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent=new Intent(this,BanzhengService.class);
        conn=new Myconn();
        //连接服务
        bindService(intent,conn,BIND_AUTO_CREATE);

    }


    //点击按钮,调用服务里面的方法
    public void btnbanzheng(View view){
        myBinder.callBanzheng(500);
    }
    //监视服务的状态
    private class Myconn implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //获取中间人对象
            myBinder= (BanzhengService.MyBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }
}

黑马Android76期学习笔记01基础--day08--start/bind开启服务、电话录音,特别广播接收者,bindService/接口调用服务内方法,混合开启服务,进程间通讯,aidl应用场景

7.通过接口调用服务内部方法

接口可以隐藏代码内部的细节,让程序员暴露自己只想暴露的方法
通过接口调用服务内部方法的步骤
1、定义一个接口,把想暴露的方法都定义在接口里面
2、定义一个中间人对象,实现我们自定义的接口
3、获取中间人对象的
4、调用服务内部方法

1、ImpService 接口

package com.fengray.ex070;

public interface ImpService {

    //把想暴露的方法定义在接口里
    public void callBanzheng(int money);
}

2、DemoService 类

package com.fengray.ex070;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;

public class DemoService extends Service {
    @Nullable
    @Override
    //把自己定义的中间人对象返回
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }
    //办证方法
    public void banzheng(int money){
        if (money>1000){
            Toast.makeText(getApplicationContext(), "我是领导,把证给办了", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(getApplicationContext(), "这点钱,还想办事情吗", Toast.LENGTH_SHORT).show();
        }
    }

    //打麻将的方法
    public void playMaJiang(){
        Log.d("TAG", "playMaJiang: 陪领导打麻将");
    }
    //洗桑拿的方法
    public  void sangna(){
        Log.d("TAG", "playMaJiang: 陪领导洗桑拿");

    }


    //定义一个中间人对象(IBinder)
    private class MyBinder extends Binder implements ImpService{
        //调用服务里的方法
        public void callBanzheng(int money){
            banzheng(money);
        }

        public void callplayMajiang(){
            playMaJiang();
        }

        public void callsangna(){
            sangna();
        }


    }

}

3、MainActivity 类

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private Myconn conn;
    private ImpService myBinder;//自定义的中间人对象
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent=new Intent(this, DemoService.class);
        conn=new Myconn();
        //连接服务
        bindService(intent,conn,BIND_AUTO_CREATE);

    }


    //点击按钮,调用服务里面的方法
    public void btnbanzheng(View view){
        //调用服务里面的方法
        myBinder.callBanzheng(500);
        //myBinder.callplayMajiang();//接口没暴露这个方法因此无法调用
        //myBinder.callsangna();//接口没暴露这个方法因此无法调用
    }
    //监视服务的状态
    private class Myconn implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //获取中间人对象
            myBinder= (ImpService) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }
}
8.混合方式开启服务

所谓混合方式是指,既想让服务在后台长期运行,又想调用服务里面的方法
1、先调用startService开启服务,能够保证服务在后台长期运行
2、调用bindService方法,去获取中间人对象
3、调用unbindService解绑服务
4、调用stopService停止服务

9.音乐播放器

1、清单文件里注册服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fengray.ex071music">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".MusicService"></service>
    </application>

</manifest>

2、定义接口文件ImpService

package com.fengray.ex071music;

public interface ImpService  {
    // 暴露方法
    public void callPlayMusic();
    public void callPauseMusic();
    public void callContinueMusic();
}

**3、定义服务文件MusicService **

package com.fengray.ex071music;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class MusicService extends Service {

    @Nullable
    @Override
    //返回我们定义的中间人对象
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    //播放音乐方法
    public void playMusic(){
        Log.d("TAG", "playMusic:   音乐播放了");
    }
    //暂停播放音乐方法
    public void pauseMusic(){
        Log.d("TAG", "playMusic:   音乐暂停了");
    }
    //继续播放音乐方法
    public void continueMusic(){
        Log.d("TAG", "playMusic:   音乐继续播放了");
    }

    //在服务的内部定义一个中间人对象(IBinder对象)
    private class MyBinder extends Binder implements ImpService{
        //调用播放音乐的方法
        @Override
        public void callPlayMusic() {
            playMusic();
        }
        //调用暂停播放音乐的方法
        @Override
        public void callPauseMusic() {
            pauseMusic();
        }
        //调用继续播放音乐的方法
        @Override
        public void callContinueMusic() {
            continueMusic();
        }
    }

}

4、主MainActivity类

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private ImpService impService=null;//定义的中间人对象
    private MyConn conn=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //混合方式开启服务
        //先调用startService,保证服务能在后台长期运行
        Intent intent=new Intent(this,MusicService.class);
        startService(intent);

        //调用bindService,目的是为了获取我们定义的中间人对象,这样就可以间接调用服务里面的方法
        conn=new MyConn();//conn返回的是IBinder对象,尽管名字是Connection的
        bindService(intent, conn,BIND_AUTO_CREATE);

    }

    public void btnPlay(View view){
        impService.callPlayMusic();
    }

    public void btnPause(View view){
        impService.callPauseMusic();
    }

    public void btnContinue(View view){
        impService.callContinueMusic();
    }

    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }

    //监听服务的状态
    public class MyConn implements ServiceConnection {

        @Override
        //当服务连接的时候
        public void onServiceConnected(ComponentName name, IBinder service) {
            impService=(ImpService)service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }
}
10.进程间通讯(aidl)

aidl介绍
本地服务:运行自己应用里面的服务
远程服务:运行在其他应用里面的服务
实现进程间通信(IPC)
aidl:安卓 接口 定义 语言
用来解决进程间通讯的

使用aidl的步骤
1、把Iservice.java文件变成一个aidl为后缀的文件
2、aidl这个语言不认识public,把public去掉
3、自动生成一个iservice.java文件,系统自动帮我们生成了一个类Stub
4、我们自己定义的中间人对象直接继承Stub即可
5、保证2个应用的aidl文件是同一个,保证aidl文件所在的包名相同
6、获取中间人对象的方式不一样

本文地址:https://blog.csdn.net/weixin_43745804/article/details/108163611