android - 如何从单独进程中的服务调用 Activity 中的方法?

标签 android android-activity service

我知道如何从 Activity 中通过aidl接口(interface)调用服务中的方法。但是如何在没有广播接收器的情况下从在单独进程中运行的服务调用 Activity 中的方法?

有什么方法可以通过相同的aidl接口(interface)或其他java接口(interface)调用我的 Activity 中的方法吗?

代码:

//aidl interface
interface IRemoteServiceCallback {

    void valueChanged();
}

//starting service in activity
Intent serviceIntent = new Intent(BackgroundService.class.getName());
serviceIntent.setPackage("com.example.service2");
startService(serviceIntent);
bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);


//aidl stub implementation in activity
private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {

    @Override
    public void valueChanged() {

        System.out.println("Callback method called");
    }
};

//service connection in activity
BackgroundService mService = null;
private ServiceConnection mConnection = new ServiceConnection() {

    public void onServiceConnected(ComponentName className, IBinder service) {

        System.out.println("Callback service connected");
        try {

            mService.registerCallback(mCallback);
        } catch (Exception e) {

            Log.e("Service2-CallbackService-Connecting:", e.toString());
        }
    }

    public void onServiceDisconnected(ComponentName className) {

        if (mService != null) {
            try {
                mService.unregisterCallback(mCallback);
            } catch (Exception e) {
                Log.e("Service2-CallbackService:", e.toString());
            }
        }
    }
};

// registering callbacks in service
public void registerCallback(IRemoteServiceCallback mCallback) {

    System.out.println("Callback registers...");
    this.mCallback = mCallback;
}

public void unregisterCallback(IRemoteServiceCallback mCallback2) {

    this.mCallback = null;
}

//calling method
mCallback.valueChanged();

最佳答案

http://developer.android.com/guide/components/aidl.html

您可以通过服务连接注册的接口(interface)使用回调。

/** 
     * This implementation is used to receive callbacks from the remote 
     * service. 
     */ 
    private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
        /** 
         * This is called by the remote service regularly to tell us about 
         * new values.  Note that IPC calls are dispatched through a thread 
         * pool running in each process, so the code executing here will 
         * NOT be running in our main thread like most other things -- so, 
         * to update the UI, we need to use a Handler to hop over there. 
         */ 
        public void valueChanged(int value) {
            mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
        } 
    }; 

    private static final int BUMP_MSG = 1;

    private Handler mHandler = new Handler() { 
        @Override public void handleMessage(Message msg) { 
            switch (msg.what) { 
                case BUMP_MSG: 
                    mCallbackText.setText("Received from service: " + msg.arg1); 
                    break; 
                default: 
                    super.handleMessage(msg); 
            } 
        } 

    }; 

//用于注册 Activity 的回调

 private ServiceConnection mConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className,
                    IBinder service) {
                // This is called when the connection with the service has been 
                // established, giving us the service object we can use to 
                // interact with the service.  We are communicating with our 
                // service through an IDL interface, so get a client-side 
                // representation of that from the raw service object. 
                ....

                // We want to monitor the service for as long as we are 
                // connected to it. 
                try { 
                    mService.registerCallback(mCallback);
                } catch (RemoteException e) {
                    // In this case the service has crashed before we could even 
                    // do anything with it; we can count on soon being 
                    // disconnected (and then reconnected if it can be restarted) 
                    // so there is no need to do anything here. 
                } 
            } 

            public void onServiceDisconnected(ComponentName className) {
                // This is called when the connection with the service has been 
                // unexpectedly disconnected -- that is, its process crashed. 
               ...
                 if (mService != null) {
                    try { 
                        mService.unregisterCallback(mCallback);
                    } catch (RemoteException e) {
                        // There is nothing special we need to do if the service 
                        // has crashed. 
                    } 
                } 
            } 
        }; 

You need to create registerCallback and unregisterCallback in service, and call the interface when required Blockquote

//来自服务的代码 fragment

IRemoteServiceCallback mCallback;
    public void registerCallback(IRemoteServiceCallback callback) {
        this.mCallback = callback;
    }

    public void unregisterCallback() {
        this.mCallback = null;
    }
    .
    .
    private void updateActivity() {
        if(mCallback != null) {
            **mCallback.valueChanged(10);**
        }
    }

关于android - 如何从单独进程中的服务调用 Activity 中的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29644584/

相关文章:

android - 如何将 JSON 响应转换为字符串并显示在屏幕上?

java - 使用谷歌地图 v2 膨胀 fragment 时出现异常

android - 如何在 android 软键盘上将 "search"显示为文本而不是搜索图标

c# - 对象引用未设置为对象的实例 #1

c++ - 窗口服务停止,但进程继续运行

symfony - 如何从数据库中获取值并将其显示在所有模板中?

android - Ktlint 自定义记者

android - 如何在 android 中调整图像大小以在扩展通知中使用它?

android - TabHost 在显示新 Activity 一段时间后显示默认 Activity

java - android中 Activity 生命周期的父类(super class)实现是做什么的?