Рендеринг Android Force GPU Как включить и отключить?

Я создаю приложение, которое требует много рисования на холсте. Я заметил, что приложение немного тормозит на устройствах с высоким разрешением (например, Nexus 7). Я видел, что в опции разработчика есть опция Force GPU. Когда Force GPU включен, мое приложение работает абсолютно гладко.

Я читал, что эта опция Force GPU называется аппаратным ускорением и доступна только для Android 3.0 и выше.

Мое приложение предназначено для Android 2.3 и выше.

Можно ли программно включить аппаратное ускорение (или Force GPU — как бы это ни называлось) на любых устройствах Android 3.0 или выше?

Что-то типа:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){

    Turn On Hardware Accelerate HERE but How can i do this?
    any code snippet would be welcome/helpful/thanks

}

person xiaowoo    schedule 03.03.2013    source источник
comment
Извините за путаницу, я создаю свое приложение на Android 2.3 API 10, поэтому на самом деле у него нет ‹application android:hardwareAccelerated=true ...› или getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams .FLAG_HARDWARE_ACCELERATED);   -  person xiaowoo    schedule 04.03.2013
comment
Вы добавили подавление в свой onCreate?   -  person wtsang02    schedule 04.03.2013
comment
Установите цель сборки на уровень API 11 или выше, а затем используйте android:hardwareAccelerated="true".   -  person CommonsWare    schedule 04.03.2013
comment
если я установлю цель сборки на уровень API 11, то я не смогу поддерживать устройства уровня API 10... Я хотел бы по-прежнему иметь возможность поддерживать API 10...   -  person xiaowoo    schedule 04.03.2013
comment
wtsang02, я попробовал ваш код, но ошибка FLAG_HARDWARE_ACCELERATED не может быть разрешена или не является полем, потому что WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED недоступен в API 10   -  person xiaowoo    schedule 04.03.2013
comment
«Если я установлю цель сборки на уровень API 11, то я не смогу поддерживать устройства уровня API 10 — да, вы можете.   -  person CommonsWare    schedule 04.03.2013


Ответы (3)


Я предполагаю, что вы уже добавили android:hardwareAccelerated в свой файл манифеста?

<application android:hardwareAccelerated="true" ...>

Именно это обеспечивает аппаратное ускорение в вашем приложении согласно руководству по аппаратному ускорению и должен делать именно то, что форсирует GPU на системном уровне.

person ianhanniballake    schedule 03.03.2013
comment
мое приложение использует Android 2.3 API 10, в нем нет android:hardwareAccelerated, поэтому оно жалуется на то, что идентификатор ресурса не найден для атрибута «hardwareAccelerated» в пакете «android» - person xiaowoo; 04.03.2013
comment
Вы можете создавать и настраивать различные уровни API. Создавайте с API 11+ и сохраняйте минимальный SDK на уровне 10. - person ianhanniballake; 04.03.2013
comment
ianhanniballake, вы говорите, что я могу создать свое приложение с использованием последней версии API (11) и сделать так, чтобы оно по-прежнему работало на устройствах с более низким API? Означает ли это, что мне просто нужно обновить цель проекта Android до последней версии API? - person xiaowoo; 04.03.2013
comment
Это точно правильно. Это android:minSdkVersion в вашем манифесте, который контролирует, на каких устройствах он будет работать, а не то, на чем вы строите. Это позволяет использовать новые API, сохраняя при этом обратную совместимость. Конечно, вам по-прежнему нужна проверка версии перед вызовом любого метода, но в этом случае XML-атрибут hardwareAccelerated просто игнорируется на устройствах до Honeycomb. - person ianhanniballake; 04.03.2013
comment
ааа, я попробую... и спасибо за ваш комментарий - person xiaowoo; 04.03.2013

Установите minSdkVersion на 10 и targetSdkVersion на максимум.

Как ниже

 <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="17" />

тогда

<application android:hardwareAccelerated="true" ...>

Теперь будет работать

А по особенностям

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB){
     view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}

or

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB){
     view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
person bmkay    schedule 22.03.2013

Если вы хотите создать свое приложение с использованием более низкого уровня API, вы можете получить доступ к методу через отражение:

    try {
        Method setLayerType = view.getClass().getMethod(
                "setLayerType", new Class[] { int.class, Paint.class });
        if (setLayerType != null)
            setLayerType.invoke(view, new Object[] { LAYER_TYPE_X, null });
    } catch (NoSuchMethodException e) {
    } catch (IllegalArgumentException e) {
    } catch (IllegalAccessException e) {
    } catch (InvocationTargetException e) {
    }

Где LAYER_TYPE_X — постоянное целочисленное значение желаемого типа слоя:

LAYER_TYPE_NONE = 0
LAYER_TYPE_SOFTWARE = 1
LAYER_TYPE_HARDWARE = 2
person Niko    schedule 04.12.2013