package org.jivesoftware.smack;

import java.util.logging.Logger;

import org.jivesoftware.smack.util.DNSUtil;
import org.jivesoftware.smack.util.dns.dnsjava.DNSJavaResolver;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.ResolverConfig;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;

public class SmackAndroid {
	private static final Logger LOGGER = Logger.getLogger(SmackAndroid.class.getName());

	private static SmackAndroid sSmackAndroid = null;

	private BroadcastReceiver mConnectivityChangedReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			LOGGER.fine("ConnectivityChange received, calling ResolverConfig.refresh() and Lookup.refreshDefault()");
			ResolverConfig.refresh();
			Lookup.refreshDefault();
		}
	};

	private static boolean receiverRegistered = false;
	private Context mCtx;

	private SmackAndroid(Context ctx) {
		// Use the application context to prevent "receiver not registered" messages
		mCtx = ctx.getApplicationContext();
		DNSUtil.setDNSResolver(DNSJavaResolver.getInstance());
	}

	/**
	 * Init Smack for Android. Make sure to call
	 * SmackAndroid.onDestroy() in all the exit code paths of your
	 * application.
	 */
	public static synchronized SmackAndroid init(Context ctx) {
		if (sSmackAndroid == null) {
			sSmackAndroid = new SmackAndroid(ctx);
		}
		sSmackAndroid.maybeRegisterReceiver();
		return sSmackAndroid;
	}

	/**
	 * Cleanup all components initialized by init(). Make sure to call
	 * this method in all the exit code paths of your application.
	 */
	public synchronized void onDestroy() {
		LOGGER.fine("onDestroy: receiverRegistered=" + receiverRegistered);
		if (receiverRegistered) {
			mCtx.unregisterReceiver(mConnectivityChangedReceiver);
			receiverRegistered = false;
		}
	}

	private void maybeRegisterReceiver() {
		LOGGER.fine("maybeRegisterReceiver: receiverRegistered=" + receiverRegistered);
		if (!receiverRegistered) {
			mCtx.registerReceiver(mConnectivityChangedReceiver, new IntentFilter(
					ConnectivityManager.CONNECTIVITY_ACTION));
			receiverRegistered = true;
		}
	}
}

@@ -848,12 +848,968 @@
 lt()
-%22);%0A
+ in new Thread%22);%0A%09%09%09// Lookup.refreshDefault may cause network I/O. So in order to prevent a NetworkOnMainThreadException,%0A%09%09%09// we refresh dnsjava in a new thread.%0A%09%09%09// Full stacktrace of the offending call:%0A%09%09%09// Caused by: android.os.NetworkOnMainThreadException%0A%09%09%09// at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1128)%0A%09%09%09// at java.net.InetAddress.lookupHostByName(InetAddress.java:385)%0A%09%09%09// at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)%0A%09%09%09// at java.net.InetAddress.getByName(InetAddress.java:289)%0A%09%09%09// at org.xbill.DNS.SimpleResolver.%3Cinit%3E(SimpleResolver.java:56)%0A%09%09%09// at org.xbill.DNS.SimpleResolver.%3Cinit%3E(SimpleResolver.java:68)%0A%09%09%09// at org.xbill.DNS.ExtendedResolver.%3Cinit%3E(ExtendedResolver.java:266)%0A%09%09%09// at org.xbill.DNS.Lookup.refreshDefault(Lookup.java:86)%0A%09%09%09// at org.xbill.DNS.Lookup.%3Cclinit%3E(Lookup.java:97)%0A%09%09%09Thread thread = new Thread() %7B%0A%09%09%09%09%09@Override%0A%09%09%09%09%09public void run() %7B%0A%09%09%09
 %09%09%09R
@@ -1833,16 +1833,19 @@
 resh();%0A
+%09%09%09
 %09%09%09Looku
@@ -1864,16 +1864,76 @@
 ault();%0A
+%09%09%09%09%09%7D%0A%09%09%09%09%7D;%0A%09%09%09thread.setDaemon(true);%0A%09%09%09thread.start();%0A
 %09%09%7D%0A%09%7D;%0A

Fix NetworkOnMainThreadException caused by dnsjava