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

    你可能感兴趣的文章
    Python:函数进阶
    查看>>
    Python:在整数的二进制表示中查找最长的二进制间隙
    查看>>
    Python:如何从二进制转换为 base 64 并返回?
    查看>>
    Python:如何以非阻塞方式读取子进程的标准输出
    查看>>
    Python:如何使用 plotly 制作阴影区域或交替背景颜色?
    查看>>
    Python:如何根据日期时间获取值的计数
    查看>>
    python:如何检测串行 COM 上的设备名称/ID
    查看>>
    Python:如何模拟 datetime.utcnow()?
    查看>>
    Python:如果DataFrames之间的其他值匹配,则对DataFrame中的值求和
    查看>>
    Python:字典思维
    查看>>
    Python:将 HEX 字符串转换为字节
    查看>>
    Python:将列表与范围列表合并
    查看>>
    Python:将列表列表初始化为一定大小,
    查看>>
    Python:带有生成器的给定集合的幂集
    查看>>
    Python:按字符的位置拆分字符串
    查看>>
    Python:替换嵌套字典中的值
    查看>>
    Python:爬取数据出现response.status_code为403解决方法
    查看>>
    Python:爬取数据出现response.status_code为418解决方法
    查看>>
    Python:生成“元组集“;来自“元组列表“;不考虑顺序
    查看>>
    Python:生成具有趋势的随机时间序列数据(例如周期性、指数衰减等)
    查看>>