You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 8中StaxXmlPullParserFactory实例化方法及XMPP连接崩溃问题求助

Hey there! Let's break down and solve your two Android technical issues step by step:

1. How to Instantiate StaxXmlPullParserFactory on Android 8 (API 26)

Android 8 and later versions removed the standard Java EE StAX APIs (like javax.xml.stream.XMLInputFactory) from the system classpath. Since org.jivesoftware.smack.xml.stax.StaxXmlPullParserFactory depends on these APIs, you can't instantiate it directly without adding compatible libraries first:

  • First, add these dependencies to your app-level build.gradle (Module level) to include the StAX API and a reliable implementation (Woodstox is a widely used choice):
    dependencies {
        // StAX API dependency
        implementation 'javax.xml.stream:stax-api:1.0-2'
        // Woodstox implementation for StAX
        implementation 'com.fasterxml.woodstox:woodstox-core:6.5.1'
    }
    
  • Then, you can either let Smack's ServiceLoader auto-detect the factory (after adding dependencies) or explicitly initialize it:
    try {
        StaxXmlPullParserFactory factory = new StaxXmlPullParserFactory();
        XmlPullParser parser = factory.newXmlParser();
        // Use the parser for your XML processing needs
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    }
    
2. Fixing the App Crash on Emulator

Looking at your crash log, the root cause is unambiguous:

java.lang.ClassNotFoundException: Didn't find class "javax.xml.stream.XMLInputFactory"

This ties directly to the missing StAX dependencies we covered above. Here's a complete fix, including critical adjustments to your code:

Step 1: Add Required Dependencies

Add the StAX API and Woodstox dependencies to your build.gradle as shown in the first issue.

Step 2: Revise Your XMPPHandler Class

Your current XMPPHandler inherits from AppCompatActivity—this is unnecessary, as it's a utility class for XMPP connections, not a UI component. Additionally, network operations like connect() must never run on the main thread (Android blocks main-thread network calls to avoid UI freezing). Here's the cleaned-up code:

import android.content.Context;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.android.AndroidSmackInitializer;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jxmpp.stringprep.XmppStringprepException;
import java.io.IOException;

// Convert to a regular utility class instead of an Activity
public class XMPPHandler {
    private XMPPTCPConnection connection;

    public void connect(Context context) {
        // Run network logic on a background thread
        new Thread(() -> {
            try {
                // Initialize Smack for Android first
                AndroidSmackInitializer.initialize(context);
                
                XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
                        .setXmppDomain("192.168.1.9")
                        .setHost("192.168.1.9")
                        .setPort(5222)
                        .setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.ifpossible)
                        // Disable hostname verification for testing with IP addresses
                        .setHostnameVerifier((hostname, session) -> true)
                        .build();
                
                connection = new XMPPTCPConnection(config);
                connection.connect();
                // Optional: Call login here if needed
                // login("your-username", "your-password");
            } catch (IOException | InterruptedException | XMPPException | SmackException | XmppStringprepException e) {
                e.printStackTrace();
            }
        }).start();
    }

    public void login(String username, String password) throws XMPPException, InterruptedException, IOException, SmackException {
        if (connection != null && connection.isConnected()) {
            connection.login(username, password);
        }
    }

    // Add a method to clean up connections when done
    public void disconnect() {
        if (connection != null && connection.isConnected()) {
            connection.disconnect();
        }
    }
}

Step 3: Ensure Proper Smack Initialization

Create or update your Application class to initialize Smack and explicitly set the parser factory, avoiding ServiceLoader inconsistencies:

import android.app.Application;
import org.jivesoftware.smack.android.AndroidSmackInitializer;
import org.jivesoftware.smack.xml.SmackXmlParser;
import org.jivesoftware.smack.xml.stax.StaxXmlPullParserFactory;
import org.xmlpull.v1.XmlPullParserException;

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        AndroidSmackInitializer.initialize(this);
        // Explicitly set the StAX parser factory to avoid loading issues
        try {
            SmackXmlParser.setXmlPullParserFactory(new StaxXmlPullParserFactory());
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
    }
}

Don't forget to register this MyApp class in your AndroidManifest.xml:

<application
    android:name=".MyApp"
    ...>
    <!-- Your activities and services go here -->
</application>

内容的提问来源于stack exchange,提问作者Salman Farid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:32:35