jordy
jordy

Reputation: 51

We use a lot of ImageButton and the App lag

for my little game i use a lot of Image Buttons! The problem is that the application is lagging on some mobiles..but i dont find the problem.

Here is a Screenshot that you can imagine it better:

enter image description here

Now the question is how I got it running smoothly ? Pls i need our help :) Here is the menu xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="de.unikatproduktion.smaragdhunter.MenueActivity"
android:background="@drawable/menuehintergrund">

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageButton
        android:layout_width="90dp"
        android:layout_height="45dp"
        android:id="@+id/btn_zurvollversion"
        android:scaleType="fitXY"
        android:background="@drawable/btnzurvollversion"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp" />

    <ImageView
        android:background="@drawable/smaragdmenueanim"
        android:id="@+id/imgshhg"
        android:scaleType="fitXY"
        android:layout_width="250dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="110dp" />

    <ImageButton
        android:layout_width="90dp"
        android:layout_height="45dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:id="@+id/btnmusikanaus"
        android:scaleType="fitXY"
        android:background="@drawable/buttonmusikanausnewclickeddddd"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="275dp"
        android:layout_marginRight="15dp"
        android:layout_gravity="right" />

    <ImageView
        android:id="@+id/zauberermenue"
        android:scaleType="fitXY"
        android:background="@drawable/zauberermenuehgg"
        android:layout_height="60dp"
        android:layout_above="@+id/btn_highscore"
        android:layout_toRightOf="@+id/btn_appbewerten"
        android:layout_toEndOf="@+id/btn_appbewerten"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="221dp"
        android:layout_width="60dp" />

    <ImageButton
        android:id="@+id/btn_appbewerten"
        android:scaleType="fitXY"
        android:background="@drawable/btnappbewerten"
        android:layout_width="90dp"
        android:layout_height="45dp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="15dp" />

    <ImageButton
        android:id="@+id/btn_start"
        android:scaleType="fitXY"
        android:background="@drawable/btnstart"
        android:layout_height="90dp"
        android:layout_alignParentBottom="true"
        android:layout_alignLeft="@+id/btn_highscore"
        android:layout_alignStart="@+id/btn_highscore"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginTop="375dp"
        android:layout_gravity="center_horizontal"
        android:layout_width="220dp" />

    <Spinner
        android:layout_width="220dp"
        android:layout_height="90dp"
        android:id="@+id/schwierigkeitsgrad"
        android:background="@drawable/btnschwierigkeit"
        android:layout_marginTop="280dp"
        android:scrollbarSize="100dp"
        android:foregroundGravity="center"
        style="@style/Widget.AppCompat.Spinner"
        android:animationCache="false"
        android:animateLayoutChanges="false"
        android:alwaysDrawnWithCache="false"
        android:clipChildren="false"
        android:elevation="0dp"
        android:layout_gravity="center_horizontal"
        android:dropDownSelector="@android:drawable/list_selector_background"
        android:popupElevation="@dimen/activity_horizontal_margin"
        android:spinnerMode="dropdown" />

    <TextView
        android:text="Die Vollversion bietet ein besseres Spielerlebnis!"
        android:singleLine="true"
        android:scrollHorizontally="true"
        android:ellipsize="marquee"
        android:marqueeRepeatLimit="marquee_forever"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:textColor="#000000"
        android:textStyle="bold"
        android:id="@+id/werbeview"
        android:textSize="20sp"
        android:layout_marginLeft="4dp"
        android:layout_gravity="bottom|center"
        android:layout_marginBottom="7dp" />

    <ImageButton
        android:layout_width="90dp"
        android:layout_height="45dp"
        android:background="@drawable/btnenglisch"
        android:id="@+id/sprache"
        android:scaleType="fitXY"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="60dp" />

    <ImageButton
        android:id="@+id/insta"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginLeft="60dp"
        android:layout_marginTop="220dp"
        android:background="#00000000"
        android:scaleType="fitXY"
        app:srcCompat="@drawable/instaiconklein" />
</FrameLayout>

Upvotes: 1

Views: 191

Answers (3)

Hesham Haikal
Hesham Haikal

Reputation: 152

Try to reuse your bitmaps , so it doesn't have to be decoded every time the user opens your game. You can use InBitmap in BitmapFactory.Optionslike in this code :

public class ImageCache {

Set<SoftReference<Bitmap>> mReusableBitmaps;

protected Bitmap getBitmapFromReusableSet(BitmapFactory.Options options) {
    Bitmap bitmap = null;

    if (mReusableBitmaps != null && !mReusableBitmaps.isEmpty()) {
        synchronized (mReusableBitmaps) {
            final Iterator<SoftReference<Bitmap>> iterator
                    = mReusableBitmaps.iterator();
            Bitmap item;

            while (iterator.hasNext()) {
                item = iterator.next().get();

                if (null != item && item.isMutable()) {
                    // Check to see it the item can be used for inBitmap.
                    if (canUseForInBitmap(item, options)) {
                        bitmap = item;

                        // Remove from reusable set so it can't be used again.
                        iterator.remove();
                        break;
                    }
                } else {
                    // Remove from the set if the reference has been cleared.
                    iterator.remove();
                }
            }
        }
    }
    return bitmap;
}

int getBytesPerPixel(Bitmap.Config config) {
    if (config == Bitmap.Config.ARGB_8888) {
        return 4;
    } else if (config == Bitmap.Config.RGB_565) {
        return 2;
    } else if (config == Bitmap.Config.ARGB_4444) {
        return 2;
    } else if (config == Bitmap.Config.ALPHA_8) {
        return 1;
    }
    return 1;
}
public boolean canUseForInBitmap(Bitmap candidate, BitmapFactory.Options targetOptions) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        // From Android 4.4 (KitKat) onward we can re-use if the byte size of
        // the new bitmap is smaller than the reusable bitmap candidate
        // allocation byte count.
        int width = targetOptions.outWidth / targetOptions.inSampleSize;
        int height = targetOptions.outHeight / targetOptions.inSampleSize;
        int byteCount = width * height * getBytesPerPixel(candidate.getConfig());
        return byteCount <= candidate.getAllocationByteCount();
    }

    // On earlier versions, the dimensions must match exactly and the inSampleSize must be 1
    return candidate.getWidth() == targetOptions.outWidth
            && candidate.getHeight() == targetOptions.outHeight
            && targetOptions.inSampleSize == 1;
}

public void addInBitmapOptions(BitmapFactory.Options options) {
    // inBitmap only works with mutable bitmaps, so force the decoder to
    // return mutable bitmaps.
    options.inMutable = true;

    if (this != null) {
        // Try to find a bitmap to use for inBitmap.
        Bitmap inBitmap = getBitmapFromReusableSet(options);

        if (inBitmap != null) {
            // If a suitable bitmap has been found, set it as the value of
            // inBitmap.
            options.inBitmap = inBitmap;
        }
    }
}
public Bitmap decodeSampledBitmapFromFile(Resources res,int id) {

    final BitmapFactory.Options options = new BitmapFactory.Options();

    BitmapFactory.decodeResource(res, id , options);

    // If we're running on Honeycomb or newer, try to use inBitmap.
    addInBitmapOptions(options);

    return BitmapFactory.decodeResource(res, id ,options);
}

I hope this works for you :) , and if not you can check this answer

Upvotes: 2

Ridcully
Ridcully

Reputation: 23665

You can turn on 'Profile GPU rendering' in Settings/Developer options to see whether it is the rendering at all, that makes your app lag.

Upvotes: 0

Omar El Halabi
Omar El Halabi

Reputation: 2128

It usually happens when the images have high resolutions. It could be the case that you have one ImageView in the whole app that could make the app crash as the device faces an overhead trying to render it.

Upvotes: 4

Related Questions