【问题标题】:android.os.BinderProxy cannot be cast to org.eclipse.paho.android.service.MqttServiceBinderandroid.os.BinderProxy 不能强制转换为 org.eclipse.paho.android.service.MqttServiceBinder
【发布时间】:2016-09-06 11:55:13
【问题描述】:

我正在使用 MqttAndroidClient 开发一个包含聊天功能的应用程序,但我在初始化客户端时遇到了问题。

我想要实现的是运行一个单独的进程(使用 :remote)来运行 mqtt 客户端以订阅代理,以便从我的聊天服务器获取消息。 远程服务是在主活动中创建的,我使用 AIDL 设置了 IPC。 我知道错误代码指出IPC有错误;但是,我似乎找不到原因,因为我很确定我已经正确设置了 AIDL。

长话短说,这是我的服务代码:

private static final String MQTT_BROKER = "________(blank on purpose)";
private String userId;
private String publishTopic;
private String subscribeTopic;
MqttAndroidClient client;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return new Chat_AIDL.Stub() {
        @Override
        public String passString(String message) throws RemoteException {
            return message;
        }
    };
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    userId = intent.getStringExtra("userId");
    publishTopic = "chat/+/" + userId + "/";
    subscribeTopic = "chat/#/" + userId + "/";

    Log.d("publishTopic", publishTopic);
    Log.d("subscribeTopic", subscribeTopic);


    establishMqttConnection();

    client.setCallback(new MqttCallback() {
        @Override
        public void connectionLost(Throwable cause) {

        }

        @Override
        public void messageArrived(String topic, MqttMessage receivedMessage) throws Exception {
            Intent in = new Intent();
            String msg = new String(receivedMessage.getPayload(), "UTF-8");

            in.putExtra("resultCode", Activity.RESULT_OK);
            in.putExtra("chatMsg", msg);
            Log.d("MQTT_RECEIVED", msg);
            LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(in);
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {

        }
    });


    Log.d("SERVICE_CHAT", "STICKY");

    super.onStartCommand(intent, flags, startId);
    return Service.START_STICKY;
}

private void establishMqttConnection() {
    MemoryPersistence memPer = new MemoryPersistence();
    client = new MqttAndroidClient(this, MQTT_BROKER, userId, memPer);
    try {
        client.connect(null, new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                Log.d("MQTT", "SUCCESS");
                subscribeMessage();
            }

            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                Log.d("MQTT", "FAILURE");
                exception.printStackTrace();
            }
        });
    } catch (MqttException e) {
        e.printStackTrace();
    }
}

private void subscribeMessage() {
    try {
        client.subscribe(subscribeTopic, 0, null, new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {

            }

            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {

            }
        });
    } catch (MqttSecurityException e) {
        e.printStackTrace();
    } catch (MqttException e) {
        e.printStackTrace();
    }
}

【问题讨论】:

    标签: java android service casting mqtt


    【解决方案1】:

    我也遇到过同样的问题,发现无法像本地服务一样处理远程服务,见issue。当mqtt服务在不同的进程中创建时,官方的例子方式就不行了。

    我解决这个问题的方法是创建自己的服务,并在与 mqtt 服务相同的进程中创建此服务:

    <application>
        <!-- skipped... -->
        <service
            android:name=".MyService"
            android:exported="false"
            android:process=":background" />
        <service  
            android:name="org.eclipse.paho.android.service.MqttService"
            android:process=":background" />
    </application>
    

    希望对你有帮助。

    【讨论】:

    • 是的@l-swifter 将 MqttService 粘贴到现有的父进程上是可行的,因为我已经有一个专门的服务在它自己的进程上运行以进行通信和做其他事情。
    【解决方案2】:

    我遇到了这个问题,因为在我们的代码中我们有两个服务:一个用于 MQTT,另一个用于与服务器同步。

    我们尝试放入单独的进程,但没有奏效。我们也尝试将它们放在相同的过程中,但它也不起作用。

    在寻找解决方案后,由于这是一个简单的 ClassCastException,我们决定下载 paho.mqtt.android 的源代码并检查该转换。

    所以,我们采取的步骤:

    • 从这里克隆存储库:Eclipse Paho MQTT Android
    • 在您的 IDE(即 Android Studio)上导入项目
    • org.eclipse.paho.android.service包的MqttAndroidClient类中修改这个方法,如下:

      @Override
          public void onServiceConnected(ComponentName name, IBinder binder) {
              if (MqttServiceBinder.class.isAssignableFrom(binder.getClass())) {
                  mqttService = ((MqttServiceBinder) binder).getService();
                  绑定服务=真;
                  // 现在我们有了可用的服务,我们实际上可以
                  // 连接...
                  做连接();
              }
          }
    • 编译并制作模块paho.mqtt.android.service'并使用您的IDE生成的aar。

    有了这个 aar,我们就没有问题了,问题也消失了。

    希望这会有所帮助。

    【讨论】:

    • 那个错误伤害了我的大脑。感谢您的解决方案,对我有用。
    【解决方案3】:

    我今天遇到了这个异常,我做了很多更改,但其中大多数都破坏了我的代码及其逻辑。这是我的逻辑,我有一个应用程序(客户端说)将数据发送到另一个应用程序(服务器说)。为此,请跟进this tutorial。我不得不对我的AndroidManifest.xml 的服务器进行一些修改,这些服务器是

    <service android:name=".service.RemoteService"
            android:process=":remote">
            <intent-filter>
                <action android:name="full.package.name.service.RemoteService" >
                </action>
            </intent-filter>
    </service> 
    

    作为@L。 Swifter 说,问题是因为我们试图从一个用于remote listening 的服务连接到 MQTT。

    为了解决这个问题,我可以解决这个问题。

    1. 创建另一个服务 RemoteServiceForMqtt
    2. 在服务RemoteService中,启动服务RemoteServiceForMqtt
    3. 在启动服务时,添加您想要发送到 Mqtt 的数据作为额外数据。
    4. 在 RemoteServiceForMqtt 中,覆盖方法 public int onStartCommand(Intent intent, int flags, int startId),在其中添加将向 mqtt 发送数据的方法。

    那是

    public class RemoteServiceForMqtt extends Service
    {
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            MqttClientUtil.getInstance(RemoteServiceForMqtt.this).reconnect(); // MqttClientUtil is a class that content all the necessary informations needed to connect to mqtt
            if (intent != null){
                Bundle bundle = intent.getExtras();
                sendToMQTT(bundle.getString("data1"),bundle.getString("data2"),bundle.getString("data3"));
            }
            return 0b1;
        }
    
    
        public void sendToMQTT(String data1, String data2,String data3) {
    
            JSONObject object = new JSONObject();
            try {
                object.put("data1", data1);
                object.put("data2", data2);
                object.put("data3", data3);
            } catch (JSONException e) {
                e.printStackTrace();
            }
    
            MqttClientUtil.getInstance( RemoteServiceForMqtt.this).publish(object.toString());
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    }
    

    在服务器的AndroidManifest.xml 中添加&lt;service android:name=".service.RemoteServiceForMqtt"/&gt;

    在RemoteService(发生异常的地方)替换为

    Intent service = new Intent(getApplicationContext(), RemoteServiceForMqtt.class);
    service.putExtra("data1","data1");
    service.putExtra("data2","data2");
    service.putExtra("data3","data3");
    startService(service);
    

    希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-03
      • 2019-06-09
      • 2017-06-02
      • 2013-07-21
      • 2016-09-26
      • 2013-03-20
      • 2020-12-06
      • 1970-01-01
      相关资源
      最近更新 更多