`

创建SurfaceView的最佳位置

阅读更多
我在网上看了许多大牛创建SurfaceView的位置都是在Activty的onCreate()中进行的,本人最近一直在做Android视频这一块,用的SurfaceView来显示视频数据。如果在Activty的

onCreate()中创建SurfaceView会遇到一些莫名奇妙的问题。

为了方便起见,我给大家写个测试,来说明问题的原因
在onCreate()中创建SurfaceView的效果图如下:


代码:
package com.t1;

import android.app.Activity;
import android.os.Bundle;
import android.view.SurfaceView;

public class T1 extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SurfaceView mv = new T3(this);
        setContentView(mv);
    } 
 
}


package com.t1;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Paint.Style;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
  
public class T3 extends SurfaceView implements Runnable, Callback {  
    private SurfaceHolder mHolder; // 用于控制SurfaceView   
    private Thread t; // 声明一条线程   
    private volatile boolean flag; // 线程运行的标识,用于控制线程   
    private Canvas mCanvas; // 声明一张画布   
    private Paint p; // 声明一支画笔   
    float m_circle_r = 10;  
  
    public T3(Context context) {  
        super(context);  
  
        mHolder = getHolder(); // 获得SurfaceHolder对象   
        mHolder.addCallback(this); // 为SurfaceView添加状态监听   
        p = new Paint(); // 创建一个画笔对象   
        p.setColor(Color.WHITE); // 设置画笔的颜色为白色   
        setFocusable(true); // 设置焦点   
    }  
  
    /** 
     * 当SurfaceView创建的时候,调用此函数 
     */  
    @Override  
    public void surfaceCreated(SurfaceHolder holder) {  
        //if(t == null) {
    	t = new Thread(this); // 创建一个线程对象   
        flag = true; // 把线程运行的标识设置成true   
        t.start(); // 启动线程   
        //}
       }  
  
    /** 
     * 当SurfaceView的视图发生改变的时候,调用此函数 
     */  
    @Override  
    public void surfaceChanged(SurfaceHolder holder, int format, int width,  
            int height) {  
    }  
  
    /** 
     * 当SurfaceView销毁的时候,调用此函数 
     */  
    @Override  
    public void surfaceDestroyed(SurfaceHolder holder) {  
        mHolder.removeCallback(this);  
        flag = false;
    }  
  
    @Override  
    public void run() {  
        while (flag) {  
            try {  
                synchronized (mHolder) {  
                    Thread.sleep(100); // 让线程休息100毫秒   
                    draw(); // 调用自定义画画方法   
                }  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } finally {  
                if (mCanvas != null) {  
                    // mHolder.unlockCanvasAndPost(mCanvas);//结束锁定画图,并提交改变。   
  
                }  
            }  
        }  
    }  
  

    private void draw() {  
        mCanvas = mHolder.lockCanvas(); 
        if (mCanvas != null) {  
        	mCanvas.drawColor(Color.TRANSPARENT,PorterDuff.Mode.CLEAR);
        	Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            paint.setColor(Color.RED);  
            paint.setStrokeWidth(10);  
            paint.setStyle(Style.FILL);  
            if (m_circle_r >= (getWidth() / 10)) {  
                m_circle_r = 0;  
            } else {  
                m_circle_r++;  
            }    
            for (int i = 0; i < 5; i++)  
                for (int j = 0; j < 8; j++)  
                    mCanvas.drawCircle(  
                            (getWidth() / 5) * i + (getWidth() / 10),  
                            (getHeight() / 8) * j + (getHeight() / 16),  
                            m_circle_r, paint);  
            mHolder.unlockCanvasAndPost(mCanvas);  
        }  
    }  
} 



原因是你在短按Home键时,程序后台运行,SurfaceView的surfaceDestroyed()方法执行了,此时销毁画图线程。所以你再次进入这个界面时,由于SurcefaceView未创建,画图线

程未启动,所以看不到任何图像。那怎样解决这个问题?

借助Activity生命周期,重写onResume()方法。
  
public class T1 extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      } 
     @Override
    protected void onResume() {
    	super.onResume();
    	SurfaceView mv = new T3(this);
        setContentView(mv);
    }
}
运行效果图如下,完美解决。

分享到:
评论

相关推荐

    在surfaceview上放置控件

    1. **创建SurfaceView**:首先,你需要创建一个SurfaceView的子类,重写其中的`onCreateSurfaceHolder()`和`onSurfaceHolderDestroyed()`方法,以处理Surface的创建和销毁。同时,可能还需要一个绘制线程来持续更新...

    SurfaceView

    SurfaceView是Android系统中一种特殊的View,主要用于处理高性能、低延迟的图形绘制,例如游戏、视频播放或相机预览等场景。它与普通的View不同,SurfaceView...记得在实践中不断调整和优化,以达到最佳的性能效果。

    surfaceview进行屏幕截图demo

    在Android开发中,SurfaceView是一种特殊的视图,它允许开发者创建高性能、低延迟的图形界面,常用于视频播放、游戏等场景。SurfaceView内部有自己的渲染线程,与UI线程分离,提高了绘制效率。本教程将围绕如何使用...

    android-SurfaceView 测试Demo

    SurfaceView可以与其他View组件共存,但需要注意避免相互间的遮挡和冲突,合理布局以达到最佳用户体验。 9. **权限管理**: 如果SurfaceView涉及到硬件加速或者摄像头等特性,可能需要申请相应的权限,如`...

    Android SurfaceView实现加载GIF动画

    2. **创建自定义的GIF播放器**:我们需要创建一个继承自`SurfaceView`的类,并在其中处理GIF的加载和播放。这个类需要包含一个`Glide`的请求构建器,用于加载GIF资源。 3. **加载GIF**:在`SurfaceHolder.Callback`...

    Android_surfaceView与layout屏幕适配总结

    然而,由于其独立性,`SurfaceView`在屏幕适配上可能会遇到一些挑战,比如大小和位置的调整。开发者需要确保`SurfaceView`在不同尺寸的屏幕上正确显示,这通常通过设置布局参数(LayoutParams)来实现,包括宽度、...

    【Android基础】(12)SurfaceView绘图API详解

    在创建SurfaceView时,通常需要重写`SurfaceHolder.Callback`接口的三个方法:`surfaceCreated()`, `surfaceChanged()`, `surfaceDestroyed()`,以便在Surface生命周期的关键时刻进行处理。 1. `surfaceCreated()`...

    Android使用SurfaceView实现墨迹天气的风车效果

    1. **创建SurfaceView**:在布局XML文件中添加SurfaceView,并在Activity中找到并初始化它。设置SurfaceHolder监听器,以便在Surface准备好时开始绘制。 2. **实现SurfaceHolder.Callback**:在Activity或自定义类...

    android中surfaceview控件的使用范例

    在Android开发中,SurfaceView是一个非常重要的视图组件,它为高性能的图形渲染提供了平台,如游戏、视频播放等...在实际项目中,开发者应根据需求选择合适的SurfaceView或其替代方案,如TextureView,以实现最佳性能。

    Android游戏开发学习(5)--实现Button悬浮于与SurfaceView之上

    5. **自定义`SurfaceView`**:如果需要更复杂的交互效果,比如让`Button`随着游戏画面移动,我们可以自定义`SurfaceView`,在绘制时考虑到`Button`的位置,并相应地调整绘制范围。 6. **性能优化**:由于`...

    SurfaceView高性能绘制(二)代码实践篇-静态图片

    接着,我们创建一个自定义的SurfaceView子类,重写`onCreateSurfaceHolderCallback`方法来监听Surface的创建、改变和销毁事件。在`surfaceCreated`回调中,我们可以初始化绘图工具,如Canvas对象,准备要绘制的图片...

    最简单的游戏小人人走路SurfaceView

    在这个“最简单的游戏小人人走路SurfaceView”项目中,我们将深入探讨如何利用`SurfaceView`来创建一个简单的游戏。 `SurfaceView`是Android系统提供的一个视图组件,它具有自己的独立渲染线程,可以高效地进行图像...

    SurfaceViewPlayVideo

    2. **创建SurfaceView** 首先,我们需要在布局文件中添加一个SurfaceView,并在代码中找到这个视图,通常通过findViewById()方法实现。然后,我们可以创建一个SurfaceHolder的Callback,用于监听Surface的状态变化...

    Android 自定义SurfaceView详解

    总的来说,自定义`SurfaceView`是Android开发中实现复杂图形、视频或游戏的重要手段,理解其工作原理和最佳实践对于优化应用性能至关重要。开发者可以根据具体需求,灵活运用`SurfaceView`的特性来实现高效且流畅的...

    安卓Android源码——(SurfaceView游戏框架).zip

    1. `surfaceCreated()`:当Surface首次创建或重新创建时调用,这是开始绘制的最佳时机。 2. `surfaceChanged()`:Surface大小或格式改变时调用,例如屏幕旋转时。 3. `surfaceDestroyed()`:Surface即将被销毁时调用...

    SurfaceViewLayout工程

    在这个工程中,开发者可能已经创建了一个自定义布局,使得SurfaceView与其他View(如Button、TextView)可以和谐共存,同时还能保持SurfaceView的高性能特性。 1. **SurfaceView介绍**: - SurfaceView是Android...

    Android在surfaceview中显示Dialog和Toast

    在Android开发中,`SurfaceView`是一个特殊类型的`View`,它允许开发者在应用程序中创建高性能的图形渲染,常用于视频播放、游戏等场景。然而,`SurfaceView`的特性可能导致标准的`Dialog`和`Toast`在显示时遇到一些...

    Android使用SurfaceView实现墨迹天气的风车效果.rar

    创建SurfaceView子类** 首先,你需要创建一个继承自SurfaceView的自定义类,并重写关键方法,如`onCreateSurfaceHolder()`、`onSurfaceCreated()`、`onSurfaceChanged()`和`onDraw()`。 ```java public class ...

    使用Camera与SurfaceView实现自定义拍照功能

    在使用`Camera`时,我们需要创建一个`SurfaceHolder`,并将其添加到`SurfaceView`中。然后,通过`Camera.setPreviewDisplay(SurfaceHolder holder)`方法将`SurfaceHolder`设置为预览的显示界面。`SurfaceView`的生命...

    Android应用源码之(SurfaceView游戏框架).zip

    通过创建一个新的线程来处理绘制任务,SurfaceView能够确保UI交互不会受到频繁的图像更新影响,从而提高了性能。 在游戏框架设计中,通常会有一个游戏循环(Game Loop)来处理游戏的逻辑更新和画面刷新。...

Global site tag (gtag.js) - Google Analytics