Android: How to fix NetworkOnMainThreadException by disabling strict mode

First and foremost, let me make it clear that I strongly advise against this. The reason why this was introduced in Android Honeycomb 3.1 is because people just didn't know they were running long IO tasks on the main thread.

Google was sick and tired of being blamed for the sluggish performance of Android so they turned it into an exception. The UI thread now times IO tasks and raises exceptions whenever it runs longer than a given threshold.

So now it's your problem, and only you can fix it.

Egk80
Yeah it stinks, but it's the truth.

You can of course disable this, but it's actually better to fix the cause than to hide the symptom. The reason why I'm sharing this is because it can be used as a "quick-fix" before you take the time to fix it properly.

Turning it off is quite simple, it's just a 2 liner.

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

Unless you're supporting Android 2.x. Then it becomes a huge pile of... reflection.

Big thanks to pixel on StackOverflow for writing this up!

/**
* This snippet allows UI on main thread.
* Normally it's 2 lines but since we're supporting 2.x, we need to reflect.
*/
private void disableStrictMode() {
// StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
// StrictMode.setThreadPolicy(policy);

try {
Class<?> strictModeClass = Class.forName("android.os.StrictMode", true, Thread.currentThread().getContextClassLoader());
Class<?> threadPolicyClass = Class.forName("android.os.StrictMode$ThreadPolicy", true, Thread .currentThread().getContextClassLoader());
Class<?> threadPolicyBuilderClass = Class.forName("android.os.StrictMode$ThreadPolicy$Builder", true, Thread.currentThread().getContextClassLoader());

Method setThreadPolicyMethod = strictModeClass.getMethod("setThreadPolicy", threadPolicyClass);

Method detectAllMethod = threadPolicyBuilderClass.getMethod("detectAll");
Method penaltyMethod = threadPolicyBuilderClass.getMethod("penaltyLog");
Method buildMethod = threadPolicyBuilderClass.getMethod("build");

Constructor<?> threadPolicyBuilderConstructor = threadPolicyBuilderClass.getConstructor();
Object threadPolicyBuilderObject = threadPolicyBuilderConstructor.newInstance();

Object obj = detectAllMethod.invoke(threadPolicyBuilderObject);

obj = penaltyMethod.invoke(obj);
Object threadPolicyObject = buildMethod.invoke(obj);
setThreadPolicyMethod.invoke(strictModeClass, threadPolicyObject);
}
catch (Exception ex) {
Log.w("disableStrictMode", ex);
}
}

Seriously, so messy but it works so I can't complain.

Sources

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog