博客
关于我
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/

    你可能感兴趣的文章
    php & 和 & (主要是url 问题)
    查看>>
    php -- 魔术方法 之 判断属性是否存在或为空:__isset()
    查看>>
    php -- 魔术方法 之 获取属性:__get()
    查看>>
    php -树-二叉树的实现
    查看>>
    PHP -算法-二路归并
    查看>>
    php 2条不一样 的json数据 怎么放在一个json里面_如果你是PHP开发者,请务必了解一下Composer...
    查看>>
    php 360 不记住密码,JavaScript_多种方法实现360浏览器下禁止自动填写用户名密码,目前开发一个项目遇到一个很 - phpStudy...
    查看>>
    regExp的match、exec、test区别
    查看>>
    php 404 自定义,APACHE 自定义404错误页面设置方法
    查看>>
    PHP 5.3.0以上推荐使用mysqlnd驱动
    查看>>
    php aes sha1解密,PHP AES加密/解密
    查看>>
    php CI框架单个file表单多文件上传例子
    查看>>
    php composer
    查看>>
    reflow和repaint引发的性能问题
    查看>>
    php csv 导出
    查看>>
    php curl 实例+详解
    查看>>
    php curl_init函数用法(http://blog.sina.com.cn/s/blog_640738130100tsig.html)
    查看>>
    php curl_multi批量发送http请求
    查看>>
    php curl请求微信发红包接口出现错误:Peer's Certificate issuer is not recognized.
    查看>>
    PHP curl请求错误汇总和解决方案
    查看>>