android实现xmppconnection服务

Posted

技术标签:

【中文标题】android实现xmppconnection服务【英文标题】:android implement xmppconnection service 【发布时间】:2013-03-23 14:28:10 【问题描述】:

我正在尝试使用 asmack 和 Openfire 创建一个基本的聊天应用程序。 我为 XMPPConnection 创建了一个绑定服务,每个 Activity 都绑定到它。

每当我尝试绑定到服务时,都会有很长的延迟。我知道 bindService 是异步的,但我想在开始寻找其他问题之前确定我的服务实现是正确的。

我在 onCreate 方法中绑定了我的服务,并尝试在 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();



【问题讨论】:

【参考方案1】:

我用 Asmack 实现了一个 Android 聊天。

我创建了一个服务。 该服务有一个带有 XmppConnection 的全局变量。 一开始我使用线程进行连接和登录。 然后我为登录用户设置 VCard,设置 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);


    

【讨论】:

【参考方案2】:

您的实现有效,您仍然需要从绑定的客户端(例如 LoginActivity)实现 CONNECT 和 DISCONNECT 等操作的处理程序。

例子:

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

但是,这种在 Service 需要运行网络操作时创建 AsyncTask 的方法将达到其在 BroadcastReceiver 中的 sendBroadcast 的限制。

如果您有 BroadcastReceiver 需要通过向 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

【讨论】:

以上是关于android实现xmppconnection服务的主要内容,如果未能解决你的问题,请参考以下文章

ClassNotFoundException 打击 XMPPConnection

Smack Android,创建一个接收消息的服务

如何将 xmpp 侦听器添加到 android 中的服务?

XMPPConnection 遇到问题

aSmack 错误:XMPPConnection 是抽象的;无法实例化

我可以从并发线程调用 XMPPConnection.sendPacket 吗?