Android 使用SurfaceView移动位图速度较慢

Android 使用SurfaceView移动位图速度较慢,android,performance,surfaceview,Android,Performance,Surfaceview,我正在为android开发一款游戏。在两个阶段之间,我想显示一部分带有路线的地图,并将其从一个城市移动到另一个城市(一个阶段到另一个阶段) 首先我想在我的手机上,这是三星Galaxy Y,240x320 Qvga ldpi 所以我有jpg格式的地图文件。这张图片是2463x602,这是一张世界地图。 我做到了,除了一件事,一切都完成了。这个“动画”对我来说太慢了 当我开始这样做时,我想,它会很快,我会用一个线程来处理速度;但问题是,这并不快 我怎样才能让它更快呢? 这是我的密码: package

我正在为android开发一款游戏。在两个阶段之间,我想显示一部分带有路线的地图,并将其从一个城市移动到另一个城市(一个阶段到另一个阶段)

首先我想在我的手机上,这是三星Galaxy Y,240x320 Qvga ldpi

所以我有jpg格式的地图文件。这张图片是2463x602,这是一张世界地图。 我做到了,除了一件事,一切都完成了。这个“动画”对我来说太慢了

当我开始这样做时,我想,它会很快,我会用一个线程来处理速度;但问题是,这并不快

我怎样才能让它更快呢? 这是我的密码:

package hu.mycompany.myproject;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MapActivity extends Activity {

    DrawView drawView;
    SoundPool soundPool;
    int soundId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
        soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
        soundId = soundPool.load(this, R.raw.airplane, 1);
        drawView = new DrawView(this);
        setContentView(drawView);
    }

    public void playSound() {
        soundPool.play(soundId, 1f, 1f, 1, 0, 1f);
    }

    @Override
    public void onResume() {
        super.onResume();
        playSound();
        drawView.resume();
    }

    @Override
    public void onPause() {
        super.onPause();
        drawView.pause();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_map, menu);
        return true;
    }

    public class DrawView extends SurfaceView implements Runnable {
        Bitmap gameMap = null;
        Thread gameLoop = null;
        SurfaceHolder surface;
        Rect rect;
        volatile boolean running;
        volatile boolean moved;

        public DrawView(Context context) {
            super(context);
            moved = false;
            surface = getHolder();
            gameMap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.map);

        }

        public void resume() {
            running = true;
            gameLoop = new Thread(this);
            gameLoop.start();
        }

        public void pause() {
            running = false;
            while (true) {
                try {
                    gameLoop.join();
                } catch (InterruptedException e) {

                }
            }
        }

        @Override
        public void run() {
            Rect canvasSize = new Rect(0, 0, 240, 320);
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            while (running) {
                if (!surface.getSurface().isValid()) {
                    continue;
                }
                if (!moved) {
                    int i;
                    for (i = 80; i <= 830; i++) {
                        Canvas canvas = surface.lockCanvas();
                        rect = new Rect(i, 250, (i + 240), 570);
                        canvas.drawBitmap(gameMap, rect, canvasSize, paint);
                        surface.unlockCanvasAndPost(canvas);
                    }
                    moved = true;
                }
            }
        }

    }

}
包hu.mycompany.myproject;
导入android.app.Activity;
导入android.content.Context;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.graphics.Paint;
导入android.graphics.Rect;
导入android.media.AudioManager;
导入android.media.SoundPool;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.Menu;
导入android.view.SurfaceHolder;
导入android.view.SurfaceView;
公共类MapActivity扩展了活动{
DrawView-DrawView;
声池声池;
内部声音ID;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
这个.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool=新的soundPool(1,AudioManager.STREAM_MUSIC,0);
soundId=soundPool.load(这个,R.raw.Airport,1);
drawView=新的drawView(此);
setContentView(drawView);
}
公共空间播放声音(){
声音池。播放(声音ID,1f,1f,1,0,1f);
}
@凌驾
恢复时公开作废(){
super.onResume();
播放声音();
drawView.resume();
}
@凌驾
公共无效暂停(){
super.onPause();
drawView.pause();
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.activity\u map,menu);
返回true;
}
公共类DrawView扩展了SurfaceView实现可运行{
位图gameMap=null;
线程gameLoop=null;
表面较厚的表面;
Rect-Rect;
易失布尔运行;
易变布尔移动;
公共绘图视图(上下文){
超级(上下文);
移动=假;
surface=getHolder();
gameMap=BitmapFactory.decodeResource(getResources(),
R.可绘制地图);
}
公众简历(){
运行=真;
gameLoop=新线程(此线程);
gameLoop.start();
}
公共空间暂停(){
运行=错误;
while(true){
试一试{
gameLoop.join();
}捕捉(中断异常e){
}
}
}
@凌驾
公开募捐{
Rect canvasSize=新的Rect(0,0,240,320);
油漆=新油漆();
paint.setAntiAlias(真);
(跑步时){
如果(!surface.getSurface().isValid()){
持续
}
如果(!移动){
int i;

对于(i=80;i1)尝试通过在photoshop中导出图片以减小图片大小,并选择png作为扩展类型 2-您应该创建两个类,一个用于处理线程,另一个用于渲染和游戏逻辑。当系统渲染时,线程将通过锁定画布来管理它。查看此链接

我忘了提到,图片的文件大小是145kb,我试图缩小图片的大小。PNG会更大,这就是我选择低质量jpg的原因。现在我将图片减半,所以现在它是82,2KB和1210x602。速度快了一点,但没有多大意义。而且,如果你看到我的代码,我会按照你说的做y、 有一个用于渲染的类,名为DrawView。(如果你推荐给我的博客是你的,请检查可下载的文件,Avira告诉我它包含病毒)不,它不是我的,我只是在搜索结果中找到的,顺便说一句,代码应该是正确的,为什么你需要下载sourcce文件?编辑:我找到了另一个,试试这个,当然我试过复制/粘贴那个项目,它在第46行告诉我:可疑方法调用;可能应该调用“draw”而不是“onDraw”我以为那是你的博客,这就是我告诉你的原因。我也检查了你的第二个链接。好的,现在我导入了这个项目,并用我的for循环扩展了MainThread.java run()函数。结果是一样的。嗯,也许这是你得到的最大性能?:)尝试使用ddms、tracer等进行一些分析,并尝试找到一些您认为占用内存/cpu太多的内容,如果您得到了您怀疑的内容,那么就可以了,否则我猜这就是您得到的内容(max:)