web-dev-qa-db-ja.com

Android 4.0.3に対してのみハードウェアアクセラレーションを無効にする方法はありますか?

私は最近、Android 4.0.3の問題に遭遇しました。アプリケーションが起動するとすぐに、次の例外が発生します(他の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)

これは、ハードウェアアクセラレーションを有効にしたことに関連しています。マニフェストでハードウェアアクセラレーションを無効にするとすぐに、アプリケーションは正常に動作し始めます。

検索を行ったところ、Romain Guyの会話で log (そのドキュメントの「drawPatch」の検索内)が見つかりました。そこでは、彼がこれを引き起こしている可能性のあることについて少し議論していますが、回避策はありません。または提案された修正、このバージョンのAndroidに対してのみハードウェアアクセラレーションを無効にする必要があるのか​​、それとも回避策があるのか​​?

御時間ありがとうございます。

16
Aldo Reyes

A-Cはコメントでこれについて言及していますが、詳しく説明します。

値ファイルでブール値を作成し、それを正しいバージョンのフォルダーに貼り付けることができます。下のマニフェストで

この投稿をチェックしてください: https://plus.google.com/+AndroidDevelopers/posts/DcsFABkyuYM

Values-v15/bools.xmlをターゲットにしたいようです

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

8
sgarman

現在、コードでウィンドウレベルでハードウェアアクセラレーションを無効にすることはできません。

有効にするだけです。マニフェストでデフォルトで無効にすることをお勧めします。

<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-ハードウェアアクセラレーションの制御で利用できます

24
João Machete

@sgarmanによってリンクされた回答は、コードへの影響が最小限で、簡単に保守できるため、気に入っています。そのリンクを拡大するために、Android v4.0.3および特定のアクティビティに対してのみハードウェアアクセラレーションを無効にするために私が行ったのはそれであり、それは私のために機能しました(バージョンを指定するxmlヘッダーを追加することを忘れないでくださいwikiエディターでは貼り付けられないため、さまざまな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>
16
Phileo99

これは、ハードウェアアクセラレーションが機能している(ときどき)面白いバグです。私はこれに対する答えをここ数日探していました。これはICSに記載されていますが、テストフォンの1つである4.1.2を実行しているSamsung Galaxy S3に気づきました。ほとんどの人がハードウェアアクセラレーションをオフにすることを提案しています。加速によってアニメーションはとても滑らかになります。したがって、draw()をオーバーライドしてnullポインター例外をキャッチすると、ハードウェアアクセラレーション機能が動作し(ほとんどの場合)、機能していないことに気付かなかったり、例外をスローしています。私の場合、カスタムビューを実行していて、カスタム描画を行う必要がありました。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()コード全体をtry and catchで囲みました。これはほとんどの電話で機能しましたが、4.1.2を実行しているsamsung s3ではちらつきを引き起こしていました。したがって、上記のメソッドを使用して、someObject.draw(mCanvas)を呼び出すたびにサイレントトライキャッチを実行し、すべてのちらつき(ハードウェアアクセラレーションビューキャッシュと新しいキャンバスの間の差異)を完全に取り除く問題を解決しました。お役に立てれば! HWAをオフにするよりもはるかに優れています!