安卓 : Can bind to a service but cannot receive instance variables

标签 android android-service smack asmack

我如何接收在服务中声明的实例变量,我能够绑定(bind)到服务,但是在访问函数以获取 XMPPConnection 以获取实例变量时,我得到空指针异常:

这是我的代码:

public class hotListener extends Activity {

    private MyService service;
    private XMPPConnection connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listener);
        if(!isMyServiceRunning()){
            startService(new Intent(this,MyService.class));
        }
    }

    @Override
    protected void onStart(){
        super.onStart();
        bindService(new Intent(this, MyService.class), mConnection,Context.BIND_AUTO_CREATE);
        System.out.println("bind done");

        connection = service.getConnection();
        System.out.println("connection received");
        receivespots();
    }

    private void receivespots() {
            //ChatManager chatmanager = connection.getChatManager();
            connection.getChatManager().addChatListener(new ChatManagerListener() {

                @Override
                public void chatCreated(Chat arg0, boolean arg1) {
                    arg0.addMessageListener(new MessageListener() {

                        @Override
                        public void processMessage(Chat arg0, Message arg1) {
                            System.out.print(arg0);
                        }
                    });
                }
            });
    }

    private boolean isMyServiceRunning() {
        System.out.println("get called");
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for(RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)){
            if(MyService.class.getName().equals(service.service.getClassName())){
                System.out.print("true");
                return true;
            }
        }
        System.out.print("false");
        return false;
    }

    @Override
      protected void onResume() {
        bindService(new Intent(this, MyService.class), mConnection,
            Context.BIND_AUTO_CREATE);
        super.onResume();
      }
     @Override
      protected void onPause() {
        unbindService(mConnection);
        super.onPause();
      }

     private ServiceConnection mConnection = new ServiceConnection() {

            @Override
            public void onServiceDisconnected(ComponentName name) {
                connection = null;
                service = null;

            }

            @Override
            public void onServiceConnected(ComponentName name, IBinder binder) {
                service = ((MyService.MyBinder)binder).getService();
                Log.d("Service","connected");
                Toast.makeText(hotListener.this,"connected",Toast.LENGTH_SHORT).show();
            }
        };
}

我的方法有什么问题吗,我正在使用asmack。

服务代码:

public class MainService extends Service{
private XMPPConnection connection;
private final IBinder mBinder = new MyBinder();

    @Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return mBinder;
}

    public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("service","started");
new Connect().execute("");
return START_STICKY;
    }

    private class Connect extends AsyncTask<String, Void, String> {

@Override
protected String doInBackground(String... params) {
    ConnectionConfiguration connConfig = new ConnectionConfiguration(SERVICE,PORT);
    XMPPConnection connection = new XMPPConnection(connConfig);
    try {
        connection.connect();
        Log.i("XMPPChatDemoActivity",
                "Connected to " + connection.getHost());
    } catch (XMPPException ex) {
        Log.e("XMPPChatDemoActivity", "Failed to connect to "
                + connection.getHost());
        Log.e("XMPPChatDemoActivity", ex.toString());
        setConnection(null);
    }
    try {
        // SASLAuthentication.supportSASLMechanism("PLAIN", 0);
        connection.login(USERNAME, PASSWORD);
        Log.i("XMPPChatDemoActivity",
                "Logged in as " + connection.getUser());

        // Set the status to available
        Presence presence = new Presence(Presence.Type.available);
        connection.sendPacket(presence);
        setConnection(connection);
        Roster roster = connection.getRoster();
        Collection<RosterEntry> entries = roster.getEntries();
        for (RosterEntry entry : entries) {
            Log.d("XMPPChatDemoActivity",
                    "--------------------------------------");
            Log.d("XMPPChatDemoActivity", "RosterEntry " + entry);
            Log.d("XMPPChatDemoActivity",
                    "User: " + entry.getUser());
            Log.d("XMPPChatDemoActivity",




        "Name: " + entry.getName());
            Log.d("XMPPChatDemoActivity",
                    "Status: " + entry.getStatus());
            Log.d("XMPPChatDemoActivity",
                    "Type: " + entry.getType());
            Presence entryPresence = roster.getPresence(entry
                    .getUser());

            Log.d("XMPPChatDemoActivity", "Presence Status: "
                    + entryPresence.getStatus());
            Log.d("XMPPChatDemoActivity", "Presence Type: "
                    + entryPresence.getType());
            Presence.Type type = entryPresence.getType();
            if (type == Presence.Type.available)
                Log.d("XMPPChatDemoActivity", "Presence AVIALABLE");
            Log.d("XMPPChatDemoActivity", "Presence : "
                    + entryPresence);

        }
    } catch (XMPPException ex) {
        Log.e("XMPPChatDemoActivity", "Failed to log in as "
                + USERNAME);
        Log.e("XMPPChatDemoActivity", ex.toString());
        setConnection(null);
    }
    return null;       
}}

    public void setConnection(XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
    // Add a packet listener to get messages sent to us
    PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
    connection.addPacketListener(new PacketListener() {
        public void processPacket(Packet packet) {
            Message message = (Message) packet;
            if (message.getBody() != null) {
                String fromName = StringUtils.parseBareAddress(message
                        .getFrom());
                Log.i("XMPPChatDemoActivity", "Text Recieved " + message.getBody()
                        + " from " + fromName );
            }
        }
    }, filter);
}
    }

   public class MyBinder extends Binder 
    {
        MainService getService() {
        return MainService.this;
      }
      }

    public XMPPConnection getconnection()
    {
if (connection != null) {
    Log.d("MainService","connection send");
    return connection;  
}
else
{
    Log.d("MainService","connection null");
return null;    
}

}}

编辑:添加代码到服务

我可以从其他 Activity 成功绑定(bind),但在这里我需要使用连接变量在单独的 Activity 中设置消息监听器

最佳答案

问题是这些行

    connection = service.getConnection();
    System.out.println("connection received");
    receivespots();

此时您的service 变量还没有设置,您是在onServiceConnected 上第一次设置它。所以我建议将这三行移到这一行之后

service = ((MyService.MyBinder)binder).getService();

编辑: 现在你在谈论一个不同的错误。我不知道,因为您没有发布服务类的代码。您需要仔细阅读文档,因为绑定(bind)到服务可能非常棘手。你需要有这样的东西:

private final IBinder mBinder = new LocalBinder();

@Override
public IBinder onBind(Intent arg0) {
    Log("onBind");
    return mBinder;
}

public class LocalBinder extends Binder {
    MyService getService() {
        return MyService.this;
    }
}

关于安卓 : Can bind to a service but cannot receive instance variables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21823015/

相关文章:

android - Android 上加速度计读数的最大值

android - 即使我在 firebase 控制台中更新了 sha1,在 play 商店中发布 .apk 后,firebase 电话身份验证也不起作用

Android区分App-In-Background和旋转事件

Android Smack 4.1.1 文件传输,错误无法建立套接字

android - 使用 smack 在消息应用程序中实现接收者状态(已读或正在打字) - Android

java - 无法通过XMPP登录openfire帐户

android - 将 GPS 坐标发送到服务器的服务

android - 水平滚动页面中的水平 ScrollView

android - 在开机时启动应用程序

android - Context.startForegroundService() 然后没有调用 Service.startForeground() 即使我停止了服务