Hello! I bring up the background, which will scroll slowly (as in Parallax Scrolling), the size of the scrollable image is 16k + by 720 pixels (7mb). When launched on powerful devices, it shows FPS 29 (HTC One), and on cheap Chinese tablets only 3 FPS (Texet TM-7024), and then throws it out altogether. Please help, how else can you optimize this code? I attach all the code of the class in which the scrolling goes.
package ru.zein4.g_break.views; import android.annotation.SuppressLint; import android.content.*; import android.graphics.*; import android.util.*; import android.view.*; import android.widget.*; public class background_menu extends SurfaceView implements SurfaceHolder.Callback { GameThread thread; int screenW; int screenH; int bgrW; int bgrH; int bgrScroll; int dBgrY; //Π‘ΠΊΠΎΡΠΎΡΡΡ ΠΏΡΠΎΠΊΡΡΡΠΊΠΈ background'a Bitmap bgr, bgrReverse; boolean reverseBackroundFirst; long timeNow; long timePrev = 0; long timePrevFrame = 0; long timeDelta; Paint exPaint = new Paint(); Rect fromRect1, toRect1, fromRect2, toRect2; public background_menu(Context context) { super(context); init(); } public background_menu (Context context, AttributeSet attrs) { super(context, attrs); init(); } public background_menu (Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public void init() { BitmapFactory.Options op = new BitmapFactory.Options(); op.inPreferenceConfig = Bitmap.Config_RGB565 bgr = BitmapFactory.decodeResource(getResources(), R.drawable.so_large_background, op); reverseBackroundFirst = false; //ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌΡΡ bgrScroll = 0; //ΠΠ°ΡΠ°Π»ΡΠ½Π°Ρ ΠΏΠΎΠ·ΠΈΡΠΈΡ ΠΏΡΠΎΠΊΡΡΡΠΊΠΈ dBgrY = 1; //Π‘ΠΊΠΎΡΠΎΡΡΡ ΠΏΡΠΎΠΊΡΡΡΠΊΠΈ getHolder().addCallback(this); setFocusable(false); exPaint.setAntiAlias(false); exPaint.setFilterBitmap(true); } @Override public void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); screenW = w; screenH = h; bgr = Bitmap.createScaledBitmap(bgr, w * 2, h, true); bgrW = bgr.getWidth(); bgrH = bgr.getHeight(); //ΠΠ΅Π»Π°Π΅ΠΌ Π²ΡΠΎΡΠΎΠΉ ΠΎΡΠ·Π΅ΡΠΊΠ°Π»Π΅Π½Π½ΡΠΉ Π±ΠΈΡΠΌΠ°ΠΏ Matrix matrix = new Matrix(); matrix.setScale(-1, 1); //ΠΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎ Π³ΠΎΡΠΈΠ·ΠΎΠ½Π°Π»ΠΈ bgrReverse = Bitmap.createBitmap(bgr, 0, 0, bgrW, bgrH, matrix, true); //Π‘ΠΎΠ·Π΄Π°ΡΠΌ Π±ΠΈΡΠΌΠ°ΠΏ ΠΈΠ· ΠΎΡΠ·Π΅ΡΠΊΠ°Π»Π΅Π½Π½ΠΎΠΉ ΠΌΠ°ΡΡΠΈΡΡ } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); fromRect1 = new Rect(0, 0, bgrW - bgrScroll, bgrH); toRect1 = new Rect(bgrScroll, 0, bgrW, bgrH); fromRect2 = new Rect(bgrW - bgrScroll, 0, bgrW, bgrH); toRect2 = new Rect(0, 0, bgrScroll, bgrH); if (!reverseBackroundFirst) { canvas.drawBitmap(bgr, fromRect1, toRect1, exPaint); canvas.drawBitmap(bgrReverse, fromRect2, toRect2, exPaint); } else{ canvas.drawBitmap(bgr, fromRect2, toRect2, exPaint); canvas.drawBitmap(bgrReverse, fromRect1, toRect1, exPaint); } if ((bgrScroll += dBgrY) >= bgrW) { bgrScroll = 0; reverseBackroundFirst = !reverseBackroundFirst; } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { thread = new GameThread(getHolder(), this); thread.setRunning(true); thread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; thread.setRunning(false); while (retry) { try { thread.join(); retry = false; } catch (Exception e) {e.printStackTrace();} } } class GameThread extends Thread { private SurfaceHolder surfaceHolder; private background_menu gameView; private boolean run = false; public GameThread(SurfaceHolder surfaceHolder, background_menu gameView) { this.surfaceHolder = surfaceHolder; this.gameView = gameView; } public void setRunning(boolean run) { this.run = run; } public SurfaceHolder getSurfaceHolder() { return surfaceHolder; } @SuppressLint("WrongCall") @Override public void run() { Canvas c; while (run) { c = null; //ΠΠ΅Π»Π°Π΅ΠΌ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ background'a ΠΊΠ°Π΄ΡΠΎΠ½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΡΠΌ. Π§ΠΈΡΠ»ΠΎ 16 Π³ΠΎΠ²ΠΎΡΠΈΡ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ Π΄ΠΎΠΏΡΡΡΠΈΠΌΡΠΉ FPS Π±ΡΠ΄Π΅Ρ 60 timeNow = System.currentTimeMillis(); timeDelta = timeNow - timePrevFrame; if (timeDelta < 16) { try { Thread.sleep(16 - timeDelta); } catch (Exception e) { e.printStackTrace(); } } timePrevFrame = System.currentTimeMillis(); try { c = surfaceHolder.lockCanvas(null); if (c != null) { synchronized (surfaceHolder) { gameView.onDraw(c); } } } finally { if (c != null) { surfaceHolder.unlockCanvasAndPost(c); } } } } } } Now I calculated the amount of RAM needed to decode a resource: 16200*720*4 = ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ 47 ΠΌΠ± . Somewhere I heard that the amount of required memory can be reduced using Bitmap.Config_RGB565 . How to apply this config?
UPDATE So, now I screwed the config to the bitmap and did the drawing without anti-aliasing, the FPS increased from 3 to 14 on Chinese devices. But optimization is still required.
((47/16)*4)=12mb (or 15mb if+\- 2blocks) - ProkletyiPirat