首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用ServiceConnection发送初始消息?

如何使用ServiceConnection发送初始消息?
EN

Stack Overflow用户
提问于 2022-07-13 17:30:53
回答 1查看 128关注 0票数 0

我有一个android服务,它连接到一个服务连接。初始化时,我想发送一个字符串,例如“测试消息”到服务连接。我该怎么做?

这是我的Service课程:

代码语言:javascript
复制
public class ExampleService extends Service {
    private final IBinder iBinder = new Messenger(new IncomingHandler(this)).getBinder();

    @Override
    public IBinder onBind(Intent intent) {
        return iBinder;
    }
}

这是我的ServiceConnection实现:

代码语言:javascript
复制
private ServiceConnection myService = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        Log.i("exampleService", "Binding Connect");
        messenger = new Messenger(iBinder);
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        messenger = null;
    }
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-13 19:00:25

ServiceConnection监视到服务的连接状态,而不是将信息传递到服务。要与服务通信,您需要使用作为参数传递给binder回调的onServiceConnected(ComponentName name, IBinder binder)

在代码示例中,您使用Messenger来执行通信,而不是直接与绑定器交互。Messenger是:

用于执行通信的绑定器的简单包装器。

执行您要求的代码的示例代码:

代码语言:javascript
复制
public class MyService extends Service {
    // if there are a lot of options, use an enum; its not 2012 anymore and devices have 4GB+ of memory
    public static final int MSG_HELLO = 1;


    private class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case MSG_HELLO:
                    final String stringMessage = (String) message.obj;
                    Toast.makeText(MyService.this.getApplicationContext(), "MyService: " + stringMessage, Toast.LENGTH_SHORT).show();
                default:
                    return;  // message not understood, ignore
            }
        }
    }

    final private Messenger messenger = new Messenger(new IncomingHandler());

    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }
}

public class MainActivity extends Activity {

    private static final String HELLO_MESSAGE = "hello originating from MyActivity";


    private Messenger messenger = null;

    private final ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            messenger = new Messenger(iBinder);

            // send a HELLO message immediately when connected
            final Message message = Message.obtain(null, MyService.MSG_HELLO, HELLO_MESSAGE);

            try {
                messenger.send(message);
            } catch (RemoteException e) {
                messenger = null;
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            messenger = null;
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Intent intent = new Intent(this, MyService.class);
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(serviceConnection);
    }
    
    // rest of implentation...
}

有关如何使用Messenger的更详细示例,请参见远程信使服务示例

几个人注意到:

  1. 如果您正在与本地服务通信(即服务与活动处于相同的过程中),我建议不要使用信使,因为这会使事情变得比必要的复杂。相反,您应该创建一个Binder的子类,该子类具有返回服务实例的方法。有关示例,请参见本地服务样本
  2. 确保每个bindService(...)都有相应的unbindService(...),反之亦然。例如,如果在bindService(...)中调用onCreate(),那么在onDestroy()中调用unbindService(...)
  3. 无论服务是本地的还是远程的,都要注意内存泄漏。IBinder实例可能停留在包含它的组件的生命周期之外的内存中,可能直到进程被破坏为止;这可能会导致严重的内存泄漏。如果您在一个活动或服务类中的子类Binder,那么使用一个静态内部类,而不是一个对服务或活动有隐式引用的非静态内部类。如果您需要对上下文或生命周期感知组件的引用,那么使用WeakReference。处理这一问题的适当方法不在这个问题的范围之内。有关员额,见:
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72970382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档