Я работаю над сетевым проектом в Android, поэтому, чтобы предотвратить принудительное закрытие на Android ICS из-за Can't do network operation on UI Thread, я должен использовать часть кода, приведенную ниже, или попытаться запустить свою сетевую операцию в другом потоке, но я не Я не хочу менять базовый код, поэтому я должен использовать приведенный ниже код в Android ICS. :

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

Как сделать уникальный файл apk для работы во всех версиях Android (> = 1.6)? android.os.StrictMode доступен для более поздних версий Android, поэтому я не могу попытаться использовать указанную выше часть кода в моем Android Activity. Итак, какое решение лучше:

  1. Использование Reflections для запуска этой части кода в более поздних версиях API ( As oracle docs, reflective operations have slower performance than their non-reflective counterparts )
  2. Измените мою цель сборки Android на Android 4.1.1 (API 16) и попробуйте изменить android:minSdkVersion в AndroidManifest.xml

Или, если вы знаете что-нибудь получше, дайте мне знать.

Заранее спасибо :)

2
Hossein Mobasher 31 Авг 2012 в 15:47
Измените свой код и удалите вещи из потока пользовательского интерфейса. Работа в сети в потоке пользовательского интерфейса даже медленнее, чем отражение
 – 
zapl
31 Авг 2012 в 16:04
Хорошая идея, но на нее можно потратить больше времени! Я хочу сделать это, не меняя конфликтов сети и потоков пользовательского интерфейса. :)
 – 
Hossein Mobasher
31 Авг 2012 в 16:08

1 ответ

Лучший ответ

Вы можете использовать BUILD.VERSION и отражение, чтобы решить эту проблему совместимости (проверено).

    if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 9) {
        try {
            // StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.LAX);
            Class<?> strictModeClass = Class.forName("android.os.StrictMode", true, Thread.currentThread()
                    .getContextClassLoader());
            Class<?> threadPolicyClass = Class.forName("android.os.StrictMode$ThreadPolicy", true, Thread.currentThread()
                    .getContextClassLoader());
            Field laxField = threadPolicyClass.getField("LAX");
            Method setThreadPolicyMethod = strictModeClass.getMethod("setThreadPolicy", threadPolicyClass);
            setThreadPolicyMethod.invoke(strictModeClass, laxField.get(null));
        } catch (Exception e) {
        }
    }
1
auselen 31 Авг 2012 в 16:35
Но StrictMode не определен в Android API 6! Итак, я должен изменить свою цель Android на Android 4.1.1 с minSdk 6?
 – 
Hossein Mobasher
31 Авг 2012 в 15:55
StrictMode доступен на уровне API 9. Я думаю, у вас должен быть minSdk для 1.6, а targetSdkVersion больше предназначен для изменений поведения / внешнего вида, поэтому, если вам это нужно, вы также можете установить это.
 – 
auselen
31 Авг 2012 в 16:00
Я определил свою цель Android для Android 4.1.1 и изменил minSdk на 6, поэтому я использую вашу часть кода в моем Activity, поэтому проблема такова: Call requires API level 9 (current min is 6): android.os.StrictMode#setThreadPolicy, а намек на eclipse использует @SuppressLint("NewApi") или @TargetApi(9). что я должен делать ?
 – 
Hossein Mobasher
31 Авг 2012 в 16:05
1
Я обновил ответ, чтобы он содержал решение на основе отражения.
 – 
auselen
31 Авг 2012 в 16:29
1
Вы можете безопасно подавить ошибки Lint. Это просто предупреждения. Так что используйте @SuppressLint ("NewApi")
 – 
nandeesh
31 Авг 2012 в 16:59