2014-02-17 2 views
1

Как получить переменные экземпляра, объявленные в службе, я могу привязываться к службе, но при доступе к функции, чтобы получить XMPPConnection для получения переменной экземпляра, я получаю Null Pointer исключение:Android: может привязываться к службе, но не может принимать переменные экземпляра

Вот мой код:

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

}}

EDIT: добавлен код для обслуживания

Я могу успешно связываться с другой деятельностью, но здесь мне нужно использовать переменные соединения для установки приемника сообщений в отдельной деятельности

+0

http://stackoverflow.com/questions/8341782/good-practices-for-services-on-android yorkw ответить несколько решить эту проблему, но – Harshit

ответ

1

Проблема заключается в таких линиях

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

На данный момент ваша переменная service не была установлена, вы устанавливаете ее в первый раз на onServiceConnected. Поэтому я бы предложил двигаться эти три линии после этой линии

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

EDIT: Теперь вы говорите о другой ошибке. Я не знаю, потому что вы не опубликовали код своего класса обслуживания. Вам нужно внимательно прочитать документацию, потому что привязка к сервису может быть очень сложной. Вы должны иметь что-то вроде этого:

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

переменная служба должна была после этого вызова bindService (новый Intent (это, HotspotService.class), mConnection, Context.BIND_AUTO_CREATE); , может быть, я должен создать экземпляр с нулевым первым – Harshit

+0

Нет, переменная 'service' не должна быть установлена ​​после bindService, потому что этот метод является асинхронным, то есть метод возвращается, но нет гарантии, что он закончил свою работу. Вот почему у вас есть обратный вызов onServiceConnected – Merlevede

+0

Все еще получая исключение Nullpointer в этой строке: service = ((MyService.MyBinder)) .getService(); Заявленное связующее как \t приватное связующее IBinder; – Harshit