6

短いバージョン: xmlでandroid:hardwareAccelerated = "false"を使用してハードウェアアクセラレーションを無効にすると、Theme.Sherlock.Light.DarkActionBarテーマの背景色がより白い「白」に変わります。 編集:これは主な質問でした。2番目の問題を強調するためにタイトルを変更しました。

mapViewに対してのみハードウェアアクセラレーションを無効にすると、一定の再描画が発生します。

ロングバージョン:

AFAIKハードウェアアクセラレーションは、APIレベル14以上でデフォルトで有効になっています。(参照)

私はAPIレベル16のビルドとテストを行っているので、ハードウェアアクセラレーションは通常オンになっていたので、これは私が見慣れていたものです。テーマは明るいですが、完全な白ではなく、明るい灰色(デフォルト)です。

マップ上にいくつかの円のオーバーレイが描画されていましたが、ズームインすると、マップビューが非常に遅くなり、logcatで「大きすぎてテクスチャにレンダリングできない」というエラーが発生していました。ハードウェアアクセラレーションをオフにすると問題が解決することを発見しました。

Androidマニフェストでアプリケーション(または個々のアクティビティ)のハードウェアアクセラレーションをオフにすると、レイアウトの背景色が変わります。薄い灰色から非常に薄い灰色、ほぼ純粋な白になります。これは正常な動作ですか?

マップビューのためだけにハードウェアアクセラレーションをオフにしてみました:

if(android.os.Build.VERSION.SDK_INT>=11) {
mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); }

これは、マップビューがハードウェアアクセラレーションされておらず、アプリの残りのハードウェアも高速化されているため、テクスチャの大きすぎるエラーを取り除くのに最適です。これは理想的なソリューションです。ただし、これにより別の問題が発生します。これにより、このコードを使用するオーバーレイのonDrawメソッドが常に呼び出されます。つまり、onDrawは、マップビューでinvalidate()を呼び出さずに、それ自体で何度も何度も呼び出されます。なぜこれが当てはまるのか、何か考えはありますか?

アップデート:

以下は、mapView(私が欲しいもの)に対してのみハードウェアアクセラレーションが無効になっている場合に、一定の再描画の問題を再現する簡単なコードです。

MapActivity:

public class SettingsActivity extends MapActivity {

private MapView mapView;
private static List<Overlay> overlayList;
private static AccuracyCircleOverlay accuracyCircleOverlay;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_manage_maps);

    mapView = (MapView) findViewById(R.id.map);

    overlayList = mapView.getOverlays();
    accuracyCircleOverlay = new AccuracyCircleOverlay(this);
    overlayList.add(accuracyCircleOverlay);
}

@Override
protected boolean isRouteDisplayed() {
    return false;
}
}

かぶせる:

public class AccuracyCircleOverlay extends Overlay {

private Context context;

public AccuracyCircleOverlay(Context context) {
    this.context = context;
}

@TargetApi(11)
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    super.draw(canvas, mapView, shadow);

    if (android.os.Build.VERSION.SDK_INT >= 11) {
        mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }                 
            Log.d("accuracy OVERLAY", "being redrawn");
}
}
4

3 に答える 3

4

私はついに問題が何であるかを理解しました。mapViewのレイヤータイプをソフトウェアに設定することは、オーバーレイの描画メソッドの内側から行うべきではありません。これを行うと、別のドローがトリガーされ、ループが発生するようです。mapViewを保持するアクティビティのonCreateに次のコードを配置すると、機能しました。これは、mapViewに、一定の再描画を行わずにソフトウェアモードでレンダリングするように指示します。

活動中:

if (android.os.Build.VERSION.SDK_INT >= 11) {
    mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}  

または、代わりにXMLで:

<com.google.android.maps.MapView
        ...
        android:layerType="software" />
于 2013-01-08T21:17:17.527 に答える
2

この回答があなたの質問の焦点に対応していないことを感謝します(MapViewハードウェアアクセラレーションがオフになっているときに、関連するオーバーレイが常に再描画される理由を疑問視していると理解しています-確かに、理由はわかりません)。ただし、ndwが示唆しているように、アクセラレーションをオンのままにして、代わりにオーバーレイに実際に描画しているもののサイズを制限することに焦点を当てるべきだと思います。

これはまさに、私が今取り組んでいるアプリケーションでやらなければならなかったことです。GPSデータのログからのルートを示すためにPath、上に上に描画しています。MapViewズームインしすぎると、Path突然消えて、LOGCATで「シェイプパスが大きすぎてテクスチャにレンダリングできません」という警告が表示されます。これを修正するための私の解決策は、マップのズームごとにを再生成することです(ズームレベルごとに、取得する実際のピクセル位置が明らかに異なるPathため、それについて考えると、とにかく実行する必要があります)。が基になっているデータ(たとえば、sのセット)によって生成されるProjection場合は、PathGeoPointProjectionパスセグメントなどが地図から離れているかどうかを判断するためのクラスであり、省略しておく必要があります(これは、GPSルートで行っていることです)。それ自体が大きくなりすぎる可能性のある単一のベクトルオブジェクト(円など)がある場合は、その領域のいずれかがマップ内にある場合に円が含まれるようにコードを設計することをお勧めしますが、ズームレベルが高い場合は、表示領域にその円の表面のごく一部を描画します(たとえば、正方形を描画します)。

于 2012-12-10T22:15:57.780 に答える
1

色はコードに固有のものではないと思います。同じことを経験しました。

GPUエミュレーションとholo_lightテーマを使用せずにエミュレーターを実行すると、背景が白になり、GPUエミュレーションを使用して実行すると、背景が明るい灰色になります。

とはいえ、ハードウェアアクセラレーションを無効にすることは、マップビューの問題に対する正しい解決策ではないと思います。レンダリングしようとしている形状が大きすぎる理由と、それを小さくするためにできることがあれば、それを調べようと思います。

于 2012-12-10T19:16:01.093 に答える