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

    你可能感兴趣的文章
    Postman还能做Mock?又学了一招!
    查看>>
    postman进行http接口测试
    查看>>
    Postman高阶技能:Collection集合批量运行!
    查看>>
    postMessage跨标签页共享数据
    查看>>
    QImage对一般图像的处理
    查看>>
    post为什么会发送两次请求?
    查看>>
    Post表单提交TextArea的值出现转译乱码问题 - Spring MVC处理表单提交
    查看>>
    Power BI 中的 Python 可视化需要什么设置?任何特定的 matplotlib 包版本或系统设置?
    查看>>
    Power BI:如何在 Power Query 编辑器中将 Python 与多个表一起使用?
    查看>>
    power english (3) main text -emotion mastery - focus
    查看>>
    POWER ENGLISH (6) - MODEL
    查看>>
    power english (1) —— passion
    查看>>
    Power English (1) 原文
    查看>>
    power English (3)原文
    查看>>
    POWER ENGLISH(7)- repetition
    查看>>
    SpringBoot中集成SpringBatch详细解析与实战示例(CSV文件读取十万条数据进行业务处理后写入Mysql数据库)
    查看>>
    powerbi 一张表在另外一张表中出现的数量_PowerBi之初步学习笔记
    查看>>
    QGIS怎样设置简体中文以及新建可编辑的多边形的图层
    查看>>
    PowerBuilder 使用自定义事件触发键盘Enter事件
    查看>>
    PowerCreatorCMS UploadResourcePic 任意文件上传漏洞复现
    查看>>