博客
关于我
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+uwsgi+django
    查看>>
    Nginx-http-flv-module流媒体服务器搭建+模拟推流+flv.js在前端html和Vue中播放HTTP-FLV视频流
    查看>>
    nginx-vts + prometheus 监控nginx
    查看>>
    Nginx下配置codeigniter框架方法
    查看>>
    Nginx之二:nginx.conf简单配置(参数详解)
    查看>>
    Nginx代理websocket配置(解决websocket异常断开连接tcp连接不断问题)
    查看>>
    Nginx代理初探
    查看>>
    nginx代理地图服务--离线部署地图服务(地图数据篇.4)
    查看>>
    Nginx代理外网映射
    查看>>
    Nginx代理模式下 log-format 获取客户端真实IP
    查看>>
    Nginx代理静态资源(gis瓦片图片)实现非固定ip的url适配网络环境映射ip下的资源请求解决方案
    查看>>
    Nginx代理静态资源(gis瓦片图片)实现非固定ip的url适配网络环境映射ip下的资源请求解决方案
    查看>>
    Nginx反向代理与正向代理配置
    查看>>
    Nginx反向代理是什么意思?如何配置Nginx反向代理?
    查看>>
    nginx反向代理解决跨域问题,使本地调试更方便
    查看>>
    nginx启动脚本
    查看>>
    Nginx在Windows下载安装启动与配置前后端请求代理
    查看>>
    Nginx多域名,多证书,多服务配置,实用版
    查看>>
    nginx开机启动脚本
    查看>>
    nginx异常:the “ssl“ parameter requires ngx_http_ssl_module in /usr/local/nginx/conf
    查看>>