我可以在服务中使用SpiceManager吗?

时间:2013-11-08 16:03:49

标签: android robospice

我正在尝试将SpiceManager附加到服务中,但我得到了:

java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.octo.android.robospice.SpiceService$SpiceServiceBinder
        at com.octo.android.robospice.SpiceManager$SpiceServiceConnection.onServiceConnected(SpiceManager.java:1072)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java)
        at android.os.Handler.handleCallback(Handler.java)
        at android.os.Handler.dispatchMessage(Handler.java)
        at android.os.Looper.loop(Looper.java)
        at android.app.ActivityThread.main(ActivityThread.java)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
        at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)
        at dalvik.system.NativeStart.main(Native Method)

服务流程看起来像这样:

class MyService extends Service {
    // ...
    SpiceManager mSpiceManager = new SpiceManager(UncachedSpiceService.class);
    // ...

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mSpiceManager.start(this);
        mSpiceManager.execute(new MyRequest(), new RequestListener<String>() {
            // Handle of request
        })
        // ...
        return START_STICKY;
    }

    // + additional calls to mSpiceManager.execute() in other methods
}

一旦服务启动,这会给我一个类强制转换异常吗?

2 个答案:

答案 0 :(得分:6)

要使用RoboSpice,使用SpiceManager和SpiceService的实体(上下文)必须位于同一进程中。

RoboSpice就像Android服务和任何其他上下文之间的桥梁。这个桥是面向对象的,允许在上下文和服务之间建立基于对象的双向通信通道。

在一个条件下,这在Android上是可能的:SpiceService和使用SpiceManager的实体必须在此过程中存在。这个非常特殊的“技巧”是Android中的一种硬编码行为,称为“本地服务绑定”。

如果此条件不成立,则无法以正确的方式绑定到RS服务。当SpiceManager绑定到SpiceService时,它将接收一个BinderProxy,无法与之共享引用:所有通信都必须基于Bundles,serializable或parcelable对象。在这种情况下,RS根本不起作用。

我已经在https://github.com/rovo89/XposedBridge/blob/master/src/de/robv/android/xposed/XposedBridge.java上查看了你的项目,看起来你正在使用相当低级别的东西,并从那里启动新的Zygote流程。我假设您通过分支zygote创建的进程不会与SpiceService本身在同一进程中,这就是您获得此异常的原因。

我很遗憾地这么说,但你不能在这个项目中使用RoboSpice。如果你找到了一个解决方法,我会非常有兴趣收到你的消息,但我不认为通过Android本身的设计它是可能的。

答案 1 :(得分:-1)

您无法从后台线程调用后台服务/线程。

你可以这样做。

public void callService() {
        try {
            org.springframework.web.client.RestTemplate rt = new org.springframework.web.client.RestTemplate();
            rt.getMessageConverters().add(
                    new MappingJacksonHttpMessageConverter());
            String url = "xyz";

            Contacts contacts = rt.postForObject(url, body,
                    Contacts.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "Called-" + e.toString());
        }
    }