博客
关于我
Android bind service讲解以及跨进程通信
阅读量:233 次
发布时间:2019-02-28

本文共 6997 字,大约阅读时间需要 23 分钟。

Android服务的启动方式与跨进程通信

Android服务作为后台程序运行,能够在没有用户界面的情况下执行任务。与普通应用程序不同,服务可以通过bind和start两种方式启动,它们的运行机制和使用场景有显著区别。本文将详细介绍Android服务的启动方式以及Messenger跨进程通信的实现方法。

服务的启动方式

Android服务可以通过两种方式启动:bind和start。bind方式需要绑定到服务,直到最后一个绑定的程序调用unbind,否则服务会持续运行。而start方式则是启动服务后,需要手动调用stopSelf或stopService来停止服务的运行。

服务的声明周期与启动方式

服务的声明周期可以通过附图了解清楚。需要注意的是,onCreate方法仅在服务第一次启动时调用一次,后续启动时会直接进入onStartCommand或onBind方法。

服务启动方式的代码示例

以下是启动服务的代码示例:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private boolean hasBound;    private Button intent_Service;    private Button start_Service;    private Button bind_Service;    private Button messenger_Service;    private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            if (msg.what == 322) {                Toast.makeText(getApplicationContext(), "receive message from server", Toast.LENGTH_SHORT).show();            }        }    };    private Messenger clientMessenger = new Messenger(handler);    private Messenger serverMessenger;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        intent_Service = (Button) findViewById(R.id.intent_service);        intent_Service.setOnClickListener(this);        start_Service = (Button) findViewById(R.id.start_service);        start_Service.setOnClickListener(this);        bind_Service = (Button) findViewById(R.id.bind_service);        bind_Service.setOnClickListener(this);        messenger_Service = (Button) findViewById(R.id.messenger_service);        messenger_Service.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.intent_service:                Intent intentService = new Intent(this, IntentTestService.class);                startService(intentService);                break;            case R.id.start_service:                Intent startService = new Intent(this, NormalService.class);                startService(startService);                break;            case R.id.bind_service:                Intent bindService = new Intent(this, NormalService.class);                if (bindService.resolveActivity(getPackageManager()) != null) {                    bindService(bindService, connection, Context.BIND_AUTO_CREATE);                }                break;            case R.id.messenger_service:                if (!hasBound) {                    Intent intent = new Intent("com.skateboard.serverservice.service.BIND");                    intent.setPackage("com.skateboard.serverservice");                    bindService(intent, messengerConnection, Context.BIND_AUTO_CREATE);                } else {                    sendMessageToServier();                }                break;        }    }    private ServiceConnection messengerConnection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            hasBound = true;            serverMessenger = new Messenger(service);            Message message = new Message();            message.what = 233;            message.replyTo = clientMessenger;            try {                serverMessenger.send(message);            } catch (RemoteException e) {                e.printStackTrace();            }        }        @Override        public void onServiceDisconnected(ComponentName name) {            hasBound = false;        }    };    private ServiceConnection connection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            NormalService.NormalBinder binder = (NormalService.NormalBinder) service;            binder.bindMethod();        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    };    private void sendMessageToServier() {        Message message = new Message();        message.what = 233;        message.replyTo = clientMessenger;        try {            serverMessenger.send(message);        } catch (RemoteException e) {            e.printStackTrace();        }    }    @Override    protected void onDestroy() {        super.onDestroy();    }}

服务的实现类

以下是服务的实现类代码:

public class IntentTestService extends IntentService {    public IntentTestService() {        super("IntentTestService");    }    @Override    protected void onHandleIntent(Intent intent) {        System.out.println("intent service start");    }}
public class NormalService extends Service {    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        System.out.println("service start");        stopSelf();        return super.onStartCommand(intent, flags, startId);    }    @Override    public IBinder onBind(Intent intent) {        NormalBinder normalBinder = new NormalBinder();        return normalBinder;    }    @Override    public void onDestroy() {        super.onDestroy();        System.out.println("stop service");    }    public class NormalBinder extends Binder {        public void bindMethod() {            System.out.println("bind method");        }    }}

跨进程通信的实现

跨进程通讯的方式主要有两种:AIDL和Messenger。AIDL是基于消息队列实现的多线程通讯,而Messenger则是基于消息队列实现的单线程通讯。以下是使用Messenger实现跨进程通讯的代码示例:

public class ServerService extends Service {    private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            if (msg.what == 233) {                Messenger clientMessenger = msg.replyTo;                Message message = new Message();                message.what = 322;                try {                    clientMessenger.send(message);                } catch (RemoteException e) {                    e.printStackTrace();                }            }        }    };    private Messenger messenger = new Messenger(handler);    @Override    public void onCreate() {        super.onCreate();        System.out.println("service create");    }    @Override    public IBinder onBind(Intent intent) {        System.out.println("bind service");        return messenger.getBinder();    }}

跨进程通讯的客户端实现

private ServiceConnection messengerConnection = new ServiceConnection() {    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        hasBound = true;        serverMessenger = new Messenger(service);        Message message = new Message();        message.what = 233;        message.replyTo = clientMessenger;        try {            serverMessenger.send(message);        } catch (RemoteException e) {            e.printStackTrace();        }    }    @Override    public void onServiceDisconnected(ComponentName name) {        hasBound = false;    }};

跨进程通讯的实现流程

  • 在客户端绑定到服务,接收服务连接回调。
  • 通过服务返回的IBinder获取Messenger对象。
  • 发送消息至服务端,服务端处理消息后回复客户端。
  • 通过上述方法,可以实现跨进程通讯,适用于需要在不同进程之间传递消息和数据的场景。

    转载地址:http://jbls.baihongyu.com/

    你可能感兴趣的文章
    Nginx配置实例-负载均衡实例:平均访问多台服务器
    查看>>
    NHibernate学习[1]
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
    查看>>
    NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
    查看>>
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>
    NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
    查看>>
    NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
    查看>>
    NIH发布包含10600张CT图像数据库 为AI算法测试铺路
    查看>>
    Nim教程【十二】
    查看>>
    Nim游戏
    查看>>
    NIO ByteBuffer实现原理
    查看>>
    Nio ByteBuffer组件读写指针切换原理与常用方法
    查看>>