Android:可以绑定到服务但无法接收实例变量

时间:2014-02-17 07:22:47

标签: android android-service smack asmack

如何接收服务中声明的实例变量,我能够绑定到服务,但在访问函数以获取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;    
}

}}

编辑:为服务添加了代码

我可以成功绑定其他活动但是在这里我需要使用连接变量在单独的活动中设置消息监听器

1 个答案:

答案 0 :(得分:1)

问题是这些行

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

此时您的service变量尚未设置,您是第一次在onServiceConnected上设置它。所以我建议在这一行之后移动这三行

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

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

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;
    }
}