Lelk Lelk
Lelk Lelk

Reputation: 21

android - opengl crash on animation

Helo. I'm experiencing strange behavior with my app. It crashes on litsview item flip animation with this error:

06-02 17:26:16.748 22310-23383/com.dealy.android A/OpenGLRenderer﹕ Error: Ambient Vertex Buffer overflow!!! used 286, total 284

I don't use any of OpenGL libs or smthing, so it's strange. Also, crash only occurs on Nexus 6 with android 5.1.

The code of list item here:

package com.dealy.android.adapter;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.content.Context;
import android.location.Location;
import android.os.Build;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.squareup.picasso.Picasso;

import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.List;

import butterknife.ButterKnife;
import butterknife.InjectView;
import database.HelperFactory;
import com.dealy.android.DealyApplication;
import com.dealy.android.R;
import com.dealy.android.util.SimpleAnimationEndListener;
import dto.GeoPoint;
import dto.ImageDTO;
import special.dto.Special;
import venue.dto.Venue;

/**
 * Created by Beyka on 13.01.2015.
 */
public class SpecialAdapter extends BaseAdapter {

    private static final DecimalFormat DEFAULT_DISTANCE_FORMAT = new DecimalFormat("##0.0");

    private final AnimatorSet fbo;
    private final AnimatorSet fbi;

    private Context context;
    private LayoutInflater inflater;

    private List<Special> values;
    private SparseBooleanArray flipArray;

    private GeoPoint lastLocation;

    Tracker t;

    public SpecialAdapter(Context context, List<Special> values, GeoPoint lastLocation) {
        fbo = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.card_flip_right_out);
        fbi = (AnimatorSet)AnimatorInflater.loadAnimator(context, R.animator.card_flip_right_in);

        this.context = context;
        inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        this.values = values;
        flipArray = new SparseBooleanArray();

        this.lastLocation = lastLocation;
    }

    public void setLastLocation(GeoPoint lastLocation) {
        this.lastLocation = lastLocation;

        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return values.size();
    }

    @Override
    public Special getItem(int position) {
        return values.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final Holder holder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item_special, parent, false);
            holder = new Holder(convertView);
            convertView.setTag(holder);
        } else{
            holder = (Holder)convertView.getTag();
        }

        Special special = getItem(position);

        fillHolder(holder, special, position);

        return convertView;
    }

    private void fillHolder(final Holder holder, Special special, final int position) {
        holder.front.setVisibility(flipArray.get(position, false) ? View.GONE : View.VISIBLE);
        holder.back.setVisibility(!flipArray.get(position, false) ? View.GONE : View.VISIBLE);

        t = ((DealyApplication) context.getApplicationContext()).getTracker(DealyApplication.TrackerName.APP_TRACKER);

        holder.more.setOnClickListener(new View.OnClickListener() {
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onClick(View v) {
                t.send(new HitBuilders.EventBuilder().setCategory("Test Catogory").setAction("Нажатие на подробности").build());

                fbi.setTarget(holder.back);
                fbo.addListener(new SimpleAnimationEndListener() {
                    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        flipArray.put(position, true);


                        holder.front.setVisibility(View.GONE);

                        holder.back.setVisibility(View.VISIBLE);
                        fbi.start();

                    }
                });
                fbo.setTarget(holder.front);
                fbo.start();
            }
        });

        holder.goBack.setOnClickListener(new View.OnClickListener() {
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onClick(View v) {
                t.send(new HitBuilders.EventBuilder().setCategory("Test Catogory").setAction("Нажатие на вернуться").build());


                fbi.setTarget(holder.front);
                fbo.addListener(new SimpleAnimationEndListener() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        flipArray.put(position, false);
                        holder.back.setVisibility(View.GONE);

                        holder.front.setVisibility(View.VISIBLE);

                        fbi.start();


                    }
                });
                fbo.setTarget(holder.back);
                fbo.start();


            }
        });

        holder.backTitle.setText(special.getName());
        holder.description.setText(special.getDescription());

        if(special.getImageLink() == "" || special.getImageLink() == null){
            for(ImageDTO image : special.getImages()){
                if(image.getWidth() >= 640){
                    Picasso.with(context).load("http://app.dev.getdealy.ru/images/" + image.getUrl()).fit().into(holder.logo);;
                }
            }

        }
        else {
            Picasso.with(context).load("http://app.dev.getdealy.ru/images/" + special.getImageLink()).fit().into(holder.logo);
        }

        Venue venue = new Venue();
        try {
            venue = HelperFactory.getHelper().getVenueDAO().getVenueById(special.getVenues().get(0));
        } catch (SQLException e) {
            e.printStackTrace();
        }

        final float[] distanceInMeters = new float[1];
        try {
            Location.distanceBetween(lastLocation.getLat(), lastLocation.getLng(), special.venue.getLat(), special.venue.getLng(), distanceInMeters);
        } catch(NullPointerException e){

        }
        double distanceInKm = distanceInMeters[0] / 1000.0;
        holder.distance.setText(context.getString(R.string.kilometers, DEFAULT_DISTANCE_FORMAT.format(distanceInKm)));
        holder.backDistance.setText(context.getString(R.string.kilometers, DEFAULT_DISTANCE_FORMAT.format(distanceInKm)));

        if(distanceInKm == 0){
            holder.distance.setVisibility(TextView.GONE);
            holder.backDistance.setVisibility(TextView.GONE);
        }

        if(special.venue.getLogoLink() != null) {
            Picasso.with(context).load("http://app.dev.getdealy.ru/images/" + special.venue.getLogoLink()).fit().into(holder.place);
            Picasso.with(context).load("http://app.dev.getdealy.ru/images/" + special.venue.getLogoLink()).fit().into(holder.backPlace);
        }
        else{
                Picasso.with(context).load("http://app.dev.getdealy.ru/images/" + special.venue.getImages().get(0)).fit().into(holder.place);
                Picasso.with(context).load("http://app.dev.getdealy.ru/images/" + special.venue.getImages().get(0)).fit().into(holder.backPlace);
        }


    }

    class Holder {
        @InjectView(R.id.front)
        View front;

        @InjectView(R.id.logoImage)
        ImageView logo;

        @InjectView(R.id.place)
        ImageView place;

        @InjectView(R.id.distanceText)
        TextView distance;

        @InjectView(R.id.more)
        Button more;

        @InjectView(R.id.back)
        View back;

        @InjectView(R.id.goBack)
        Button goBack;

        @InjectView(R.id.backTitle)
        TextView backTitle;

        @InjectView(R.id.backPlace)
        ImageView backPlace;

        @InjectView(R.id.backDistance)
        TextView backDistance;

        @InjectView(R.id.description)
        TextView description;

        @InjectView(R.id.card)
        RelativeLayout card;

        private Holder(View view) {
            ButterKnife.inject(this, view);
        }
    }
}

Upvotes: 2

Views: 623

Answers (2)

张子浩
张子浩

Reputation: 11

@high sea company `s answer is right. Thank you!!! You can try like this:

in AndroidManifest.xml application:

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

in Activity :

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

In layout XML :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingLeft="2dp"
android:layerType="software" //**close hardwareAccelerated**
android:paddingRight="2dp" >

in View:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Upvotes: 1

high sea company
high sea company

Reputation: 11

i have resolve this, the reason is : you had open the hardwareAccelerated attribute , you must close it in your manifest.xml like this

    android:hardwareAccelerated = "false"

    ......
    >

This problem is caused by more than 6.0 of Android's system automatically open the default hardware acceleration, but sometime we had no need to used it, Because most of the hardware capacity is still insufficient.

hope can help you!

Upvotes: 1

Related Questions