2013-03-23 55 views
2

我正在嘗試使用asmack和Openfire創建一個基本的聊天應用程序。 我已經爲XMPPConnection創建了綁定服務,並且每個Activity都綁定了它。安卓android xmppconnection服務

每當我嘗試綁定到服務時,都會有很長的延遲。我知道bindService是異步的,但我想確保在開始查找其他問題之前,我的服務實現是正確的。

我在onCreate方法中綁定我的Service並嘗試訪問onStart中的連接。

我對此仍然陌生,但我懷疑我在線程方面做了一些錯誤。現在我的應用程序運行的方式,只有當我嘗試從OnClickListener訪問它時,mBound變量纔會返回true。在Listener中發生了什麼,這會產生如此巨大的差異?我試圖找到OnClick方法的代碼,但我找不到它。

我XMPPConnectionService是這樣的:

包com.example.smack_text;

import java.io.File; 
import org.jivesoftware.smack.ConnectionConfiguration; 
import org.jivesoftware.smack.XMPPConnection; 
import org.jivesoftware.smack.XMPPException; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Binder; 
import android.os.Build; 
import android.os.IBinder; 
import android.util.Log; 
import android.widget.Toast; 

public class XMPPService extends Service{ 

XMPPConnection connection; 
// private final IBinder mBinder = new LocalBinder(); 


@Override 
public void onCreate(){ 
super.onCreate(); 
Log.d("service","created"); 
} 

/** 
* Class used for the client Binder. Because we know this service always 
* runs in the same process as its clients, we don't need to deal with IPC. 
*/ 
@Override 
public IBinder onBind(Intent intent) { 
Log.d("sevice","bound"); 
LocalBinder mBinder = new LocalBinder (this); 
return mBinder; 
} 

public class LocalBinder extends Binder { 
XMPPService service; 

public LocalBinder (XMPPService service) 
{ 
this.service = service; 
} 

public XMPPService getService(){ 
return service; 
} 

//   XMPPService getService() { 
//    return XMPPService.this; 
//   } 
} 

public void connect(final String user, final String pass) { 
Log.d("Xmpp Alex","in service"); 

ConnectionConfiguration config = new ConnectionConfiguration("10.0.2.2",5222); 

//   KEYSTORE SETTINGS 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
config.setTruststoreType("AndroidCAStore"); 
config.setTruststorePassword(null); 
config.setTruststorePath(null); 
} 
else { 
config.setTruststoreType("BKS"); 
String path = System.getProperty("javax.net.ssl.trustStore"); 
if (path == null) 
path = System.getProperty("java.home") + File.separator + "etc" 
     + File.separator + "security" + File.separator 
     + "cacerts.bks"; 
    config.setTruststorePath(path); 
} 

//   Create XMPP Connection 

connection = new XMPPConnection(config); 

new Thread(new Runnable() { 
@Override 
public void run() { 

try { 
connection.connect(); 
connection.login(user, pass); 
if(connection.isConnected()){ 
Log.d("Alex", "connected biatch!"); 
} 
else{ 
Log.d("Alex","not connected"); 
} 


} catch (XMPPException e) { 
e.printStackTrace(); 
} 
} 
}).start(); 
} 
public void disconnect(){ 
if(connection.isConnected()){ 
connection.disconnect(); 
} 
else{ 
Toast.makeText(getApplicationContext(), "not connected", Toast.LENGTH_LONG).show(); 
} 
} 
} 

回答

2

我實現了與Asmack的Android聊天。

我已經創建了一個服務。 該服務具有XmppConnection的全局變量。 在開始我使用線程進行連接和登錄。 然後我設置電子名片爲登錄的用戶,設置rosterListener 終於定下connection.addPacketListener 我有一個BroadcastReceiver活動端更新活動,並

@Override 
    public IBinder onBind(Intent arg0) { 

     return mBinderXmpp; 
    } 

    public class BinderServiceXmpp extends Binder { 
     ServiceXmpp getService() { 
      return ServiceXmpp.this; 
     } 
    } 


    private Runnable sendUpdatesToUI = new Runnable() { 
     public void run() { 
      DisplayInfo(); 
      handler.postDelayed(this, 2000); // 2 segundos 
     } 
    }; 
    private void DisplayInfo() { 
     isRunning = true; // flag to know if service is running 
     Intent tempIntent; 
     tempIntent = new Intent(BROADCAST_ACTION); 
     tempIntent.putExtra("UPDATE_OPTION", UPDATE_ACTION); 
     sendBroadcast(tempIntent); 


    } 
0

你實現的作品,你還需要實現像CONNECT行動的處理程序和DISCONNECT從您的客戶端綁定(例如LoginActivity)。

例子:

class IncomingHandler extends Handler { // Handler of incoming messages from clients bound. 
    @Override 
    public void handleMessage(android.os.Message msg) { 
     switch (msg.what) { 
      case MSG_CONNECT_XMPP: 
       new AsyncTask<Void, Void, Boolean>(){ 
        @Override 
        protected Boolean doInBackground(Void... params) { 
         // Do connection 
        } 

        @Override 
        protected void onPostExecute(Boolean aBoolean) { 
         // Notify the connection status 
        } 
       }.execute(); 
       break; 
      case MSG_DICCONNECT_XMPP: 
       new AsyncTask<Void, Void, Boolean>(){ 
        @Override 
        protected Boolean doInBackground(Void... params) { 
         // Do disconnection 
        } 

        @Override 
        protected void onPostExecute(Boolean aBoolean) { 
         // Notify the connection status 
        } 
       }.execute(); 

       break; 
      default: 
       super.handleMessage(msg); 
     } 
    } 
} 

但是,創建的AsyncTask隨時隨地的服務需要運行一個網絡行動將在廣播接收器達到它的極限爲sendBroadcast的這種做法。

如果你有廣播接收器需要開始或發送消息給XMPPService停止連接,你有這樣的事情:

public class NetworkConnectivityReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     NetworkInfo network = cm.getActiveNetworkInfo(); 

     network = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 

     if (XmppService.isRunning() && network.isConnected()) { 
      context.sendBroadcast(new Intent(XmppService.ACTION_CONNECT)); 
     } else if (XmppService.isRunning() && !network.isConnected()) { 
      context.sendBroadcast(new Intent(XmppService.ACTION_DISCONNECT)); 
     } 
    } 
} 

然後,你需要在XmppService實現廣播監聽器類。 但是,您不能在廣播偵聽器中運行AsyncTask!

將保持選項在我的帖子在這裏描述:

Android - Best option to implement Networking Class