首页 > 其他分享 >深入Android架构(从线程到AIDL)_18 SurfaceView的UI多线程02

深入Android架构(从线程到AIDL)_18 SurfaceView的UI多线程02

时间:2025-01-08 22:30:40浏览次数:3  
标签:02 AIDL void private SurfaceHolder mHolder new 多线程 public

目录

2、 使用SurfaceView画2D图

范例一

设计GameLoop(把小线程移出来)

范例二


2、 使用SurfaceView画2D图

范例一
  • 以SurfaceView绘出Bitmap图像
  • 设计SpriteView类别来实作SurfaceHolder.Callback接口
  • 首先来看个简单的程序,显示出一个Bitmap图像。这个图像就构成Sprite动画的基本图形。这个图像如下:

   

// SpriteView.java
// ………
public class SpriteView implements SurfaceHolder.Callback{
    private SpriteThread sThread;
    private Paint paint;
    private Bitmap bm;
    public SpriteView(Bitmap bmp) { bm = bmp; }
    @Override public void surfaceCreated(SurfaceHolder holder) {
        sThread = new SpriteThread(holder, this);
        sThread.start();
    }

    @Override public void surfaceDestroyed(SurfaceHolder holder) {}
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format,int width, int height) {}
    protected void onDraw(Canvas canvas) {
    paint= new Paint();
    canvas.drawColor(Color.WHITE);
    canvas.drawBitmap(bm, 10, 10, paint);
}

public class SpriteThread extends Thread{
    private SpriteView mView;
    private SurfaceHolder mHolder;
    private Canvas c;
    SpriteThread(SurfaceHolder h, SpriteView v){
        mHolder = h mView = v;
    }

    public void run(){
        try{
            c = mHolder.lockCanvas(null);
            synchronized (mHolder){
            mView.onDraw(c);
            }
        }finally{
            if(c!=null)
            mHolder.unlockCanvasAndPost(c);
        }
    }
}
设计GameLoop(把小线程移出来)

// SpriteView.java
// ……..
public class SpriteView implements SurfaceHolder.Callback{
    private SpriteThread sThread;
    private Paint paint;
    private Bitmap bm;
    public SpriteView(Bitmap bmp) { bm = bmp; }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        sThread = new SpriteThread(holder, this);
        sThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    { }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { }
    protected void onDraw(Canvas canvas) {
        paint= new Paint();
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(bm, 10, 10, paint);
    }
}

// SpriteThread.java
//……….
public class SpriteThread extends Thread {
    private SpriteView mView;
    private SurfaceHolder mHolder;
    private Canvas c;
    SpriteThread(SurfaceHolder h, SpriteView v){
        mHolder = h; mView = v;
    }

    public void run(){
        try{
            c = mHolder.lockCanvas(null);
            synchronized (mHolder){ mView.onDraw(c); }
        }finally{
            if(c!=null){ mHolder.unlockCanvasAndPost(c); }
        }
    }
}

// myActivity.java
// ……..
public class myActivity extends Activity implements OnClickListener {
    private SurfaceView sv = null;
    private Button ibtn;
    private Bitmap bm;
    private SpriteView spView;

    @Override 
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        sv = new SurfaceView(this);
        bm = BitmapFactory.decodeResource(
        getResources(), R.drawable.walk_elaine);
        spView = new SpriteView(bm);
        sv.getHolder().addCallback(spView);

        LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(200, 200);
        param.topMargin = 10; param.leftMargin = 10;
        layout.addView(sv, param);
        //----------------------------------------------
        ibtn = new Button(this); ibtn.setOnClickListener(this);
        ibtn.setText("Exit");
        ibtn.setBackgroundResource(R.drawable.gray);
        LinearLayout.LayoutParams param1 = new LinearLayout.LayoutParams(200, 65);
        param1.topMargin = 10; param1.leftMargin = 10;
        layout.addView(ibtn, param1);
        setContentView(layout);
    }
    public void onClick(View v) { finish(); }
}
范例二
  • 让图像在SurfaceView里旋转

         

  • 在MySurfaceView里定义一个DrawThread类,它诞生一个单独的线程来执行画图的任务。
  • 当主线程侦测到绘图画面(Surface)被开启时,就会诞生DrawThread对象,启动新线程去画图。
  • 一直到主要线程侦测到绘图画面被关闭时,就停此正在绘图的线程。
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private DrawThread mThread;
    MySurfaceView(Context context) {
        super(context);
        getHolder().addCallback(this);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        mHolder = holder;
        mThread = new DrawThread();
        mThread.start(); 
    }


    public void surfaceDestroyed(SurfaceHolder holder) {
        mThread.finish();
        mThread = null;
    }

    public void surfaceChanged(SurfaceHolder holder, int format,int w, int h) { }

    class DrawThread extends Thread {
        int degree = 36;
        boolean mFinished = false;
        DrawThread() { super(); }

        @Override public void run() {
            Bitmap bmp = BitmapFactory.decodeResource(getResources(),
            R.drawable.x_xxx);
            Matrix matrix;
            degree = 0;

            while(!mFinished){
                Paint paint = new Paint(); paint.setColor(Color.CYAN);
                Canvas cavans = mHolder.lockCanvas();
                cavans.drawCircle(80, 80, 45, paint);
                //------ rotate -----------------------------
                matrix = new Matrix(); matrix.postScale(1.5f, 1.5f);
                matrix.postRotate(degree);
                Bitmap newBmp= Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
                bmp.getHeight(), matrix, true);
                cavans.drawBitmap(newBmp, 50, 50, paint);
                mHolder.unlockCanvasAndPost(cavans);
                degree += 15;
                try { Thread.sleep(100);
                } catch (Exception e) {}
            }
        }
        void finish(){ mFinished = true; }
    }
}

 

// ac01.java-
//……..
public class ac01 extends Activity {
    @Override protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        MySurfaceView mv = new MySurfaceView(this);
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(200, 150);
        param.topMargin = 5;
        layout.addView(mv, param);
        setContentView(layout);
    }
}

标签:02,AIDL,void,private,SurfaceHolder,mHolder,new,多线程,public
From: https://blog.csdn.net/soarfeng/article/details/145019019

相关文章

  • 深入Android架构(从线程到AIDL)_17 SurfaceView的UI多线程01
    1、View与SurfaceView之区别SurfaceView是View的子类,其内嵌了一个用来绘制的Surface。当SurfaceView成为可见时,就会诞生Surface;反之当SurfaceView被隐藏时,就会删除Surface,以便节省资源。程序里可以控制Surface的大小,SurfaceView可控制Surface的绘图位置。View组件是由UI线......
  • 242有效的字母异位词 349. 两个数组的交集 202快乐数
    这几道都比较简单,主要是熟悉哈希的操作classSolution{public:boolisAnagram(strings,stringt){intalphab[26]={0};for(inti=0;i<s.size();i++){alphab[s[i]-'a']++;}for(inti=0;i<t......
  • 【模拟电子技术】02-PN结的形成
    【模拟电子技术】02-PN结的形成半导体就是导电能力介于导体和半导体之间的东西,本征半导体即纯净的半导体。导电靠自由电子,可看到自由电子即使是本征激发也少,导电能力也不够。自由电子撞在空穴中,就是复合(与本征激发相反),两者发生的频率决定着载流子的浓度,其实是温度的改变决定......
  • Docker更换镜像源(2025.1最新可用镜像,全网最详细)
    文章目录前言可用镜像源汇总换源方法1-临时换源换源方法2-永久换源(推荐)常见问题及对应解决方案补充1.如何测试镜像源是否可用换源速通版(可以直接无脑复制粘贴)前言由于各种网络政策,在国内访问DockerHub速度会非常缓慢,大家一般都会采取更换镜像源的方式来进行加速。......
  • Codeforces Round 986 (Div. 2) CF2028 代码集
    CodeforcesRound986(Div.2)CF2028代码集目录CodeforcesRound986(Div.2)CF2028代码集CF2028A-Alice'sAdventuresin''Chess''CF2028B-Alice'sAdventuresinPermutingCF2028C-Alice'sAdventuresinCuttingCakeCF2024D-A......
  • 「GDKOI2023 提高组」异或图
    可以说是计数大杂烩了吧。我们试着进行容斥:每次选定若干条边,钦定这些边两端的值相等。容斥系数显然是\((-1)^{|E|}\)。然后对这些连通块我们把它们的最小值当作\(a_i\)拿来跑异或的问题。实际上我们就是要把原图划分成若干连通块,答案就是每个连通块的容斥系数之积乘上新异或问......
  • 2025.1.8 练习赛总结
    总览本文同步发表与:洛谷:https://www.luogu.com.cn/article/hdzdhnif。博客园:<>。打得不好,在赛时只做了A题。昨晚的睡眠使我刚好处于困和不困的叠加态,导致想题的时候脑子极乱。A:Gym103430F。B:CF578B。C:CF1407D。D:洛谷P11122。E:CF1208D。A-Gym103430F-X-Mag......
  • 2025新春源码免费送
    我们常常在日常生活中感到时间过得异常缓慢,仿佛未来遥不可及。然而,当我们回过头去审视过去,才发现时间早已悄然溜走,许多曾经等待的日子已经过去。时间总是在不经意间流逝,让人意识到它的宝贵和不可逆转。尽管如此,我们依然应对未来保持从容的态度。生活充满了无数的可能性,未来依然充......
  • P9108 [PA2020] Malowanie płotu
    P9108[PA2020]Malowaniepłotu题意有一个\(n\timesm\)的方格,你需要对每一列涂一个非空连续段,要求相邻列的涂色连续段有交。问涂色方案数。\(n\timesm\le10^7\)。思路我们需要一个\(O(nm)\)的算法,但是不好直接设一个\(O(nm)\)的状态。很容易想到设\(f_{i,l,r......
  • 2025.1.8 鲜花
    Nim的变种グランドエスケープ空飛ぶ羽根と引き換えに繋ぎ合う手を選んだ僕ら没有选择飞翔的翅膀而是选择十指相扣的我们それでも空に魅せられて夢を重ねるのは罪か却仍然向往着天空反复做着同样的梦这有错吗夏は秋の背中を見てその顔を思い浮かべる夏天望着秋天......