2013-03-23 116 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