单独线程中的XMPP连接 - 仍然被Android操作系统关闭?

时间:2014-03-18 10:36:57

标签: android multithreading xmpp android-service asmack

我的应用程序包含许多服务(企业交付应用程序),它连接到XMPP服务器以发布报告。它的主要工作非常出色。然而,在奇怪的情况下,当连接(1 / 3G)时,连接需要太长时间,操作系统会杀死应用程序。令我讨厌的是,连接是由Alarm Manager启动的服务产生的,我使用的是AndroidConnectionConfiguration(aSmack lib),它显然产生了一个单独的线程,用于连接以远离NetworkOnMainUIException。然而,每隔一段时间,我的应用程序仍然会发出一个sigabrt信号6.为什么会发生这种情况?我没有在用户界面或附近做任何事情,并且认为无论时间如何,Android都会在完成或超时之前将其单独留下来?或者我错了吗?

我能做些什么来阻止这种情况发生吗?我不在乎XMPP是否已连接,因为它总是会在有能力时重试并发送,但我无法让应用程序崩溃。

编辑我应该说我正在使用aSmack 0.8.10 - 和Openfire 3.9.1。但它们不是问题,而且效果非常好。只有在奇怪的情况下连接需要太长时间且Android才会杀死它。

编辑2 部分代码:

package com.goosesys.dta_pta_test.Singletons;

import org.jivesoftware.smack.AndroidConnectionConfiguration;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.SmackAndroid;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;

import android.content.Context;

import com.google.gson.Gson;
import com.goosesys.dta_pta_test.MessageListenerService;
import com.goosesys.gooselib.Logging;
import com.goosesys.gooselib.Utilities.AppSettings;
import com.goosesys.gooselib.Utilities.Utility;

public class XmppConnector 
{
    private static XmppConnector instance;
    private static boolean isConnected = false;
    private static AndroidConnectionConfiguration acc;
    private static XMPPConnection xConnection;
    private static Context context;


    public static void init(Context contxt)
    {
        if(instance == null)
        {
            instance = new XmppConnector();
        }

        context = contxt;
    }

    public static XmppConnector getInstance()
    {
        return instance;
    }

    public static boolean connect() throws XMPPException
    {
        if(isConnected)
            return true;

        SmackAndroid.init(context);
        acc = new AndroidConnectionConfiguration(AppSettings.XMPP_SERVER_HOST,
                AppSettings.XMPP_SERVER_PORT, "Smack");
        acc.setSecurityMode(SecurityMode.disabled);
        xConnection = new XMPPConnection(acc);

        xConnection.addConnectionListener(new ConnectionListener(){
            @Override
            public void reconnectionSuccessful()
            {
                Logging.Debug("XmppConnector", "...reconnected to XMPP Server");
            }

            @Override
            public void reconnectionFailed(Exception e)
            {
                Logging.Debug("XmppConnector", "...reconnection failed: " + e);
            }

            @Override
            public void reconnectingIn(int seconds)
            {
                Logging.Debug("XmppConnector", "...reconnecting in: " + seconds);
            }

            @Override
            public void connectionClosedOnError(Exception e)
            {
                Logging.Debug("XmppConnector", "...connection closed on error: " + e);
            }

            @Override
            public void connectionClosed()
            {
                Logging.Debug("XmppConnector", "...connection closed");
            }                   
        });

        xConnection.connect();
        if(xConnection.isConnected())
        {
            isConnected = true;

            // LOGIN ONCE CONNECTED TO THE SERVER //
            xConnection.login(Utility.getAndroidID(context),
                    AppSettings.XMPP_KEYSTORE_PASSWORD);
            // CREATE CHAT MANAGER //
            xConnection.getChatManager().addChatListener(new ChatManagerListener(){
                @Override
                public void chatCreated(final Chat chat, boolean createdLocally)
                {
                    if(!createdLocally)
                        chat.addMessageListener(new MessageListenerService(context));
                }
            });
        }
        else
        {
            isConnected = false;
        }

        return isConnected;
    }

    public static boolean sendMessage(String jsonObj)
    {
        Message m = new Gson().fromJson(jsonObj, Message.class);
        if(m == null)
        {
            Logging.Error("XmppConnector", "Message object is null.. Aborting");
            return false;
        }

        if(isConnected)
        {
            xConnection.sendPacket(m);
            return true;
        }
        else
        {
            return false;
        }
    }
}

以及启动它的小型服务:

公共类BGCollectorProc扩展了IntentService {     private DatabaseHelper dbHelper;

public BGCollectorProc() 
{
    super("BGCollectorProc");       
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{   
    Logging.Debug("BGCollectorProc", "Spinning...");    
    //dbHelper = DatabaseHelper.getHelper(getApplicationContext());

    try
    {
        // initialise the connection
        XmppConnector.init(this);
        // get the static reference
        XmppConnector.getInstance();
        // connect to the server
        if(XmppConnector.connect())
        {
            Logging.Info("BGCollectorProc", "CONNECTED TO XMPP SERVER");
        }
    }
    catch(XMPPException e)
    {
        e.printStackTrace();
    }

    /*
    // Worker thread area //
    try {
        postDeliveries();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    postGeoLogs();
    */

    return Service.START_NOT_STICKY;
}

干杯。

1 个答案:

答案 0 :(得分:1)

SIGABRT通常意味着在达尔维克内发生了致命的事情。 Android ActivityManager不会杀死你的进程。由于VM故障,VM会终止自身。通常会有更多关于故障的信息。也许您没有将日志识别为与SIGABRT相关。至少我希望在日志中找到有关SIGABRT原因的更多信息。

BTW:拥有活动XMPPConnection的服务是粘性Android服务的理想候选者,只要XMPPConnection处于活动状态,该服务就应该运行。