Есть ли способ отключить аппаратное ускорение только для Android 4.0.3? - программирование
Подтвердить что ты не робот

Есть ли способ отключить аппаратное ускорение только для Android 4.0.3?

Я недавно наткнулся на проблему с android 4.0.3, где Im получает следующее Исключение, как только приложение запускается (на других версиях Android оно отлично работает):

java.lang.NullPointerException
at android.view.GLES20RecordingCanvas.drawPatch(GLES20RecordingCanvas.java:97)
at android.graphics.NinePatch.draw(NinePatch.java:125)
at android.graphics.drawable.NinePatchDrawable.draw(NinePatchDrawable.java:189)
at android.widget.ImageView.onDraw(ImageView.java:892)
at android.view.View.draw(View.java:10978)
at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
at android.view.View.getDisplayList(View.java:10415)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597)
at android.view.View.getDisplayList(View.java:10380)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597)
at android.view.View.getDisplayList(View.java:10380)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597)
at android.view.View.getDisplayList(View.java:10380)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597)
at android.view.View.getDisplayList(View.java:10380)
at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:842)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:1910)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

Это связано с тем, что аппаратное ускорение включено, как только я отключу его в манифесте, приложение начинает работать нормально.

Проделав поиск, я нашел log (внутри этого поиска doc для "drawPatch" ) на какой-то разговор Ромена Гая, где он обсуждает немного о том, что может быть причиной этого, хотя нет обходного пути или исправления, интересно, я должен отключить аппаратное ускорение только для этой версии android, или если есть обходной путь для этого?

Спасибо за ваше время.

4b9b3361

Ответ 1

Итак, A-C упоминает это в своем комментарии, но позвольте мне уточнить.

Вы можете создать логическое значение в файле значений и вставить его в папку с правильной версией. В вашем манифесте под

Отправляй сообщение: https://plus.google.com/+AndroidDevelopers/posts/DcsFABkyuYM.

Похоже, вам захочется настроить таргетинг на значения-v15/bools.xml

http://developer.android.com/reference/android/os/Build.VERSION_CODES.html#ICE_CREAM_SANDWICH_MR1

Ответ 2

В настоящее время вы не можете отключить аппаратное ускорение на уровне окна с помощью кода.

Включить его только. Я предлагаю вам отключить его по умолчанию в вашем манифесте:

<application android:hardwareAccelerated="false">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

а затем включите его для всех других версий:

if (Build.VERSION.SDK_INT != Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
            getWindow().setFlags(
                    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        }

Вы можете отключить аппаратное ускорение для отдельного представления во время выполнения с помощью следующего кода:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Эта информация доступна в Android - Управление ускорением аппаратного обеспечения

Ответ 3

Мне нравится ответ, связанный с @sgarman, потому что он оказывает минимальное влияние на код и легко поддерживается. Просто чтобы расширить эту ссылку, вот что я сделал, чтобы отключить аппаратное ускорение только для Android v4.0.3 и только для определенной активности, и это сработало для меня (не забудьте добавить заголовки xml, определяющие версию и кодировку в различные файлы bool.xml, поскольку редактор вики не разрешил мне вставлять его):

AndroidManifest.xml: идентифицируйте действие, в котором размещается нарушающий вид, и вставьте его в это действие:

<activity
    android:hardwareAccelerated="@bool/isNotIceCreamSandwich"
    ...
</activity>

путь к файлу: res/values ​​/bool.xml:

<resources>
    <bool name="isNotIceCreamSandwich">true</bool>
</resources>

путь к файлу: res/values-v14/bool.xml:

<resources>
    <bool name="isNotIceCreamSandwich">false</bool>
</resources>

путь к файлу: res/values-v16/bool.xml:

<resources>
    <bool name="isNotIceCreamSandwich">true</bool>
</resources>

Ответ 4

Это забавная ошибка, потому что аппаратное ускорение работает (иногда). Я искал ответ на этот вопрос в течение последних двух дней. Его документально подтвердили в ICS, но я заметил это на одном из моих тестовых телефонов, Samsung Galaxy S3 работает 4.1.2 Большинство людей предлагают отключить аппаратное ускорение. Я не хотел этого делать, аппаратное ускорение делает мои анимации такими шелковистыми. Поэтому я нашел, что если я переопределяю draw(), попробую и поймаю исключение нулевого указателя, что аппаратные ускоренные функции работают (в большинстве случаев), и достаточно, чтобы вы никогда не замечали, что они не работают или не бросают исключение. В моем случае я делал пользовательский просмотр и имел какой-то пользовательский чертеж. Простая проверка для null не работает (canvas == null), поэтому эта ошибка является болью. Так что я сделал это:

    @Override
public void draw(Canvas canvas) {
    try{
        super.draw(canvas);
        mCanvas=canvas;
    }catch(java.lang.NullPointerException e){
        Log.e("mytag","MyCustomView::draw():"+e);
    }
    if(mCanvas==null)
        return;     
...

затем молча попытайтесь поймать любой NPE в отдельных заявлениях о выводе. В первый раз, когда я увидел эту ошибку, я окружил весь код draw() в попытке и поймать. Это работало для большинства телефонов, но на samsung s3, работающем на 4.1.2, это вызывало мерцание. Таким образом, я использовал вышеупомянутый метод и молчал, пытаясь поймать каждый вызов someObject.draw(mCanvas) и решил проблему, полностью удаляя все мерцание (несоответствие между аппаратным ускоренным кешем представления и новым холстом). Надеюсь это поможет! Лучше, чем отключить HWA!