文档章节

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

march_kk
 march_kk
发布于 2017/05/05 10:43
字数 688
阅读 50
收藏 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
博文 18
码字总数 2847
作品 0
西安
程序员
图片和图形之构建一个OpenGL ES环境(10)

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

lichong951
05/26
0
0
android动态设置listview的高度

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

PaleJustice
2015/08/30
139
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
0
listItem.measure(0, 0) 空指针问题

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

似水流年0_0
2015/12/14
811
0
ListView与BUtton的问题重写BaseAdapter

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

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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

基于TP5的微信的公众号获取登录用户信息

之前讲过微信的公众号自动登录的菜单配置,这次记录一下在TP5项目中获取自动登录的用户信息并存到数据库的操作 基本的流程为:微信设置自动登录的菜单—>访问的URL指定的函数里获取用户信息—...

月夜中徘徊
57分钟前
0
0
youTrack

package jetbrains.teamsys.license.runtime; 计算lis package jetbrains.ring.license.reader; 验证lis 安装后先不要生成lis,要把相关文件进行替换 ring-license-checker-1.0.41.jar char......

max佩恩
今天
0
0
12.17 Nginx负载均衡

Nginx负载均衡 下面的dig看到可以返回2个IP,就是解析出来的IP,这样我们可以做负载均衡。 dig www.qq.com 1.vim /usr/local/nginx/conf/vhost/fuzai.conf 2.添加如下配置 upstream qq //定义...

芬野de博客
今天
0
0
SSE(Server Send Event 服务端发送事件)

package com.example.demo.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframe......

Canaan_
今天
0
0
jvm调优

1.jvm运行模式 client模式:启动快,占用内存少,jit编译器生成代码的速度也更快. server模式:主要优势在于代码优化功能,这个功能对于服务器应用而言尤其重要. tiered server模式:结合了client与...

Funcy1122
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部