文档章节

GLSurfaceView布局内使用报空指针问题

march_kk
 march_kk
发布于 2017/05/05 10:43
字数 688
阅读 46
收藏 0
点赞 0
评论 0
<android.opengl.GLSurfaceView
        android:id="@+id/gls_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

1.异常

崩溃日志

java.lang.NullPointerException
  at android.opengl.GLSurfaceView.surfaceCreated(GLSurfaceView.java:531)
  at android.view.SurfaceView.updateWindow(SurfaceView.java:601)
  at android.view.SurfaceView.access$000(SurfaceView.java:94)
  at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:183)

(备注:GLSurfaceView属于framework层,有些厂商是定制的,与标准的sdk代码会有些不同。)

找到GLSurfaceView的崩溃的那一行(实际位置GLSurfaceView.Java:522)

   public void surfaceCreated(SurfaceHolder holder) {
        mGLThread.surfaceCreated();
    }

 

既然是空指针异常,显然mGLThread对象为空。

由此,找到mGLThread初始化的地方

 

  public void setRenderer(Renderer renderer) {
        checkRenderThreadState();
        if (mEGLConfigChooser == null) {
            mEGLConfigChooser = new SimpleEGLConfigChooser(true);
        }
        if (mEGLContextFactory == null) {
            mEGLContextFactory = new DefaultContextFactory();
        }
        if (mEGLWindowSurfaceFactory == null) {
            mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
        }
        mRenderer = renderer;
        mGLThread = new GLThread(mThisWeakRef);
        mGLThread.start();
    }

 

发现mGLThread是在渲染器设置的时候进行初始化

顺便再来看看GLSurfaceView的构造函数

 

 /**
     * Standard View constructor. In order to render something, you
     * must call {@link #setRenderer} to register a renderer.
     *(这里已经提示我们,必须先设置一个渲染器)
     */
    public GLSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

 

原来是画面加载的时候去调用渲染,但是布局里面没有设置渲染器所以就崩了。

2.使用

网上常见的GLSurfaceView使用方法

 ...
    GLSurfaceView mGLView = new GLSurfaceView(this); 
    mGLView.setRenderer(new DemoRenderer()); 
    //设置渲染器,其中DemoRenderer实现GLSurfaceView.Renderer

    setContentView(mGLView);
    ...

 

如果实在想在布局里使用的话,用DemoGLSurfaceView继承GLSurfaceView 
构造函数里面设置好适配器。

DemoGLSurfaceView.java

 


package test.com.asproject;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.view.MotionEvent;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * Created by Seselin on 2016/4/1.
 */
public class DemoGLSurfaceView extends GLSurfaceView {
    DemoRenderer mRenderer;

    public DemoGLSurfaceView(Context context) {
        super(context);
        //为了可以激活log和错误检查,帮助调试3D应用,需要调用setDebugFlags()。
        this.setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
        mRenderer = new DemoRenderer();
        this.setRenderer(mRenderer);
    }

    public DemoGLSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //为了可以激活log和错误检查,帮助调试3D应用,需要调用setDebugFlags()。
        this.setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
        mRenderer = new DemoRenderer();
        this.setRenderer(mRenderer);
    }

    public boolean onTouchEvent(final MotionEvent event) {
        //由于DemoRenderer对象运行在另一个线程中,这里采用跨线程的机制进行处理。使用queueEvent方法
        //当然也可以使用其他像Synchronized来进行UI线程和渲染线程进行通信。
        this.queueEvent(new Runnable() {

            @Override
            public void run() {
            }
        });

        return true;
    }

    class DemoRenderer implements GLSurfaceView.Renderer {

        @Override
        public void onDrawFrame(GL10 gl) {
            //每帧都需要调用该方法进行绘制。绘制时通常先调用glClear来清空framebuffer。
            //然后调用OpenGL ES其他接口进行绘制
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        }

        @Override
        public void onSurfaceChanged(GL10 gl, int w, int h) {
            //当surface的尺寸发生改变时,该方法被调用,。往往在这里设置ViewPort。或者Camara等。
            gl.glViewport(0, 0, w, h);
        }

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // 该方法在渲染开始前调用,OpenGL ES的绘制上下文被重建时也会调用。
            //当Activity暂停时,绘制上下文会丢失,当Activity恢复时,绘制上下文会重建。
        }
    }
}

 

布局内配置

    <test.com.asproject.DemoGLSurfaceView
        android:id="@+id/gls_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </test.com.asproject.DemoGLSurfaceView>

 

© 著作权归作者所有

共有 人打赏支持
march_kk
粉丝 0
博文 16
码字总数 2847
作品 0
西安
程序员
图片和图形之构建一个OpenGL ES环境(10)

原文 概要 构建一个OpenGL ES环境 为了在Android应用程序中使用OpenGL ES绘制图形,您必须为它们创建一个视图容器。其中一种更直接的方法是实现a GLSurfaceView和a GLSurfaceView.Renderer。...

lichong951 ⋅ 05/26 ⋅ 0

android动态设置listview的高度

如果是非linearlayout布局,获取listview的item的高度的时候,用listitem.measure()会报空指针错误,这个问题有什么办法解决没

PaleJustice ⋅ 2015/08/30 ⋅ 0

openGL+GLSurfaceView和MediaPlayer+GLSurfaceView与视频

Android MediaPlayer+SurfaceView播放视频(附Demo)- http://blog.csdn.net/junzia/article/details/52704129 在播放网络上的视频流时,Android原生的MediaPlayer支持两种协议,HTTP和RTSP,...

shareus ⋅ 2017/09/23 ⋅ 0

listItem.measure(0, 0) 空指针问题

在android中有时候scrollView需要嵌套listview,当scrollView嵌套listview时,会出现listview显示不全的问题,这时候有很多解决的办法,其中一个类似下面的代码: public void setListViewH...

似水流年0_0 ⋅ 2015/12/14 ⋅ 0

ListView与BUtton的问题重写BaseAdapter

用调试看了,没跳到MyAdapter类,直接报空指针异常的警告,不是异常 最后页面还是正常的显示了,就是没有数据 下面是我的布局文件

马里士多德 ⋅ 2013/02/01 ⋅ 2

单例模式和volatile关键字

  越来越感觉编程的世界是真正符合自然的世界,真正遵循自然的规律。在程序的世界中事情几乎是平等的,即使不平等也是有据可循,任何技术问题也可讨论的,无论结果如何,总是0与1的差别。 ...

王小贱_ww ⋅ 2017/10/23 ⋅ 0

Android Studio配置Annotations

配置了好几次Annotations,这次配置又忘了配置步骤了,所有记录下自己配置的步骤. 我的环境是Android studio 1、 在app的build.gradle中添加下面代码 apply plugin: 'com.android.application...

SunnyTime ⋅ 2016/02/18 ⋅ 0

通过spring自动注入的对象,使用反射调用其方法之后,无法获取返回值

使用了spring + spring mvc 构建项目,在controller 里面, 被调用的 MessageService 接口及其下面的实现类MessageServiceImpl 通过注解 @resource 自动注入到controller 在调用的方法的时候,...

Lyon4j ⋅ 2015/10/28 ⋅ 6

Android listview addHeaderView 和 addFooterView 详解

addHeaderView()方法:主要是向listView的头部添加布局 addFooterView()方法:主要是向listView的底部添加布局 需要注意的是添加布局的时候应该添加从父容器开始添加,而不能直接添加父容器中...

程序袁_绪龙 ⋅ 2015/08/05 ⋅ 2

手把手教你使用OpenGL ES

>话不多说,拿起键盘就是干。OpenGL ES可以实现3D效果,而且在性能要求比较高的情况,或者一般的自定义View难以达到的效果可以考虑一下。就像官方说的,OpenGL ES直接通过GPU进行图形加速,唯...

C6C ⋅ 01/03 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring Bean基础

1、Bean之间引用 <!--如果Bean配置在同一个XML文件中,使用local引用--><ref bean="someBean"/><!--如果Bean配置在不同的XML文件中,使用ref引用--><ref local="someBean"/> 其实两种......

霍淇滨 ⋅ 25分钟前 ⋅ 0

05、基于Consul+Upsync+Nginx实现动态负载均衡

1、Consul环境搭建 下载consul_0.7.5_linux_amd64.zip到/usr/local/src目录 cd /usr/local/srcwget https://releases.hashicorp.com/consul/0.7.5/consul_0.7.5_linux_amd64.zip 解压consu......

北岩 ⋅ 28分钟前 ⋅ 0

Webpack 4 api 了解与使用

webpack 最近升级到了 v4.5+版 01 官方不再支持 node4 以下版本 官方不再支持 node4 以下版本官方不再支持 node4 以下的版本,所以如果你的node版本太低,先开始升级node吧!话说node10 ...

NDweb ⋅ 37分钟前 ⋅ 0

使用nodeJs安装Vue-cli

Vue脚手架就是一个Vue框架开发环境 脚手架的意思是帮你快速开始一个vue的项目,也就是给你一套vue的结构,包含基础的依赖库,只需要 npm install就可以安装,让我们不需要为了编辑或者一些其...

木筏笔歆 ⋅ 今天 ⋅ 0

【微信小程序开发实战】0x00.开发前准备工作

写在开始 本人资深后端码农一枚,近期项目需求,接触到了微信小程序,将学习过程整理成文分享给小伙伴们,由于是边学边整理难免有表述不对的地方,望大家及时指正,感谢。 本人微信号: dream...

dreamans ⋅ 今天 ⋅ 0

linux redis的安装和php7下安装redis扩展

安装redis服务器 (1)下载安装包: $ wget http://download.redis.io/releases/redis-2.8.17.tar.gz (2)编译程序: $ tar xzf redis-2.8.17.tar.gz $ cd redis-2.8.17 $ make $ cd src &&......

concat ⋅ 今天 ⋅ 0

Guava EventBus源码解析

一、EventBus使用场景示例 Guava EventBus是事件发布/订阅框架,采用观察者模式,通过解耦发布者和订阅者简化事件(消息)的传递。这有点像简化版的MQ,除去了Broker,由EventBus托管了订阅&...

SaintTinyBoy ⋅ 今天 ⋅ 0

http怎么做自动跳转https

Apache 版本 如果需要整站跳转,则在网站的配置文件的<Directory>标签内,键入以下内容: RewriteEngine on RewriteCond %{SERVER_PORT} !^443$ RewriteRule ^(.*)?$ https://%{SERVER_NAME......

Helios51 ⋅ 今天 ⋅ 0

Python爬虫,抓取淘宝商品评论内容

作为一个资深吃货,网购各种零食是很频繁的,但是能否在浩瀚的商品库中找到合适的东西,就只能参考评论了!今天给大家分享用python做个抓取淘宝商品评论的小爬虫! 思路 我们就拿“德州扒鸡”...

python玩家 ⋅ 今天 ⋅ 0

MySQL 内核深度优化

MYSQL数据库适用场景广泛,相较于Oracle、DB2性价比更高,Web网站、日志系统、数据仓库等场景都有MYSQL用武之地,但是也存在对于事务性支持不太好(MySQL 5.5版本开始默认引擎才是InnoDB事务...

java高级架构牛人 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部