我在网上看了许多大牛创建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);
}
}
运行效果图如下,完美解决。
分享到:
相关推荐
1. **创建SurfaceView**:首先,你需要创建一个SurfaceView的子类,重写其中的`onCreateSurfaceHolder()`和`onSurfaceHolderDestroyed()`方法,以处理Surface的创建和销毁。同时,可能还需要一个绘制线程来持续更新...
SurfaceView是Android系统中一种特殊的View,主要用于处理高性能、低延迟的图形绘制,例如游戏、视频播放或相机预览等场景。它与普通的View不同,SurfaceView...记得在实践中不断调整和优化,以达到最佳的性能效果。
在Android开发中,SurfaceView是一种特殊的视图,它允许开发者创建高性能、低延迟的图形界面,常用于视频播放、游戏等场景。SurfaceView内部有自己的渲染线程,与UI线程分离,提高了绘制效率。本教程将围绕如何使用...
SurfaceView可以与其他View组件共存,但需要注意避免相互间的遮挡和冲突,合理布局以达到最佳用户体验。 9. **权限管理**: 如果SurfaceView涉及到硬件加速或者摄像头等特性,可能需要申请相应的权限,如`...
2. **创建自定义的GIF播放器**:我们需要创建一个继承自`SurfaceView`的类,并在其中处理GIF的加载和播放。这个类需要包含一个`Glide`的请求构建器,用于加载GIF资源。 3. **加载GIF**:在`SurfaceHolder.Callback`...
然而,由于其独立性,`SurfaceView`在屏幕适配上可能会遇到一些挑战,比如大小和位置的调整。开发者需要确保`SurfaceView`在不同尺寸的屏幕上正确显示,这通常通过设置布局参数(LayoutParams)来实现,包括宽度、...
在创建SurfaceView时,通常需要重写`SurfaceHolder.Callback`接口的三个方法:`surfaceCreated()`, `surfaceChanged()`, `surfaceDestroyed()`,以便在Surface生命周期的关键时刻进行处理。 1. `surfaceCreated()`...
1. **创建SurfaceView**:在布局XML文件中添加SurfaceView,并在Activity中找到并初始化它。设置SurfaceHolder监听器,以便在Surface准备好时开始绘制。 2. **实现SurfaceHolder.Callback**:在Activity或自定义类...
在Android开发中,SurfaceView是一个非常重要的视图组件,它为高性能的图形渲染提供了平台,如游戏、视频播放等...在实际项目中,开发者应根据需求选择合适的SurfaceView或其替代方案,如TextureView,以实现最佳性能。
5. **自定义`SurfaceView`**:如果需要更复杂的交互效果,比如让`Button`随着游戏画面移动,我们可以自定义`SurfaceView`,在绘制时考虑到`Button`的位置,并相应地调整绘制范围。 6. **性能优化**:由于`...
接着,我们创建一个自定义的SurfaceView子类,重写`onCreateSurfaceHolderCallback`方法来监听Surface的创建、改变和销毁事件。在`surfaceCreated`回调中,我们可以初始化绘图工具,如Canvas对象,准备要绘制的图片...
在这个“最简单的游戏小人人走路SurfaceView”项目中,我们将深入探讨如何利用`SurfaceView`来创建一个简单的游戏。 `SurfaceView`是Android系统提供的一个视图组件,它具有自己的独立渲染线程,可以高效地进行图像...
2. **创建SurfaceView** 首先,我们需要在布局文件中添加一个SurfaceView,并在代码中找到这个视图,通常通过findViewById()方法实现。然后,我们可以创建一个SurfaceHolder的Callback,用于监听Surface的状态变化...
总的来说,自定义`SurfaceView`是Android开发中实现复杂图形、视频或游戏的重要手段,理解其工作原理和最佳实践对于优化应用性能至关重要。开发者可以根据具体需求,灵活运用`SurfaceView`的特性来实现高效且流畅的...
1. `surfaceCreated()`:当Surface首次创建或重新创建时调用,这是开始绘制的最佳时机。 2. `surfaceChanged()`:Surface大小或格式改变时调用,例如屏幕旋转时。 3. `surfaceDestroyed()`:Surface即将被销毁时调用...
在这个工程中,开发者可能已经创建了一个自定义布局,使得SurfaceView与其他View(如Button、TextView)可以和谐共存,同时还能保持SurfaceView的高性能特性。 1. **SurfaceView介绍**: - SurfaceView是Android...
在Android开发中,`SurfaceView`是一个特殊类型的`View`,它允许开发者在应用程序中创建高性能的图形渲染,常用于视频播放、游戏等场景。然而,`SurfaceView`的特性可能导致标准的`Dialog`和`Toast`在显示时遇到一些...
创建SurfaceView子类** 首先,你需要创建一个继承自SurfaceView的自定义类,并重写关键方法,如`onCreateSurfaceHolder()`、`onSurfaceCreated()`、`onSurfaceChanged()`和`onDraw()`。 ```java public class ...
在使用`Camera`时,我们需要创建一个`SurfaceHolder`,并将其添加到`SurfaceView`中。然后,通过`Camera.setPreviewDisplay(SurfaceHolder holder)`方法将`SurfaceHolder`设置为预览的显示界面。`SurfaceView`的生命...
通过创建一个新的线程来处理绘制任务,SurfaceView能够确保UI交互不会受到频繁的图像更新影响,从而提高了性能。 在游戏框架设计中,通常会有一个游戏循环(Game Loop)来处理游戏的逻辑更新和画面刷新。...