SurfaceView源码以及崩溃剖析

1 在eclipse中查看Android源代码

假设我们想参看Activity类的源代码,按着Ctrl键,左击它,现实的结果却看不到代码的,提示的信息便是“找不到Activity.class文件”。下载好Android源码之后,点击Attached Source,选择External location

External Folder文件夹菜单,选择Android所在的目录即可

http://jingyan.baidu.com/article/5d368d1e01df803f60c057f8.html

2 SurfaceView的继承关系

public class android.view.SurfaceView extendsandroid.view.View

3 如何知道Activity控件渲染完毕,可以监听事件Activity是否获得焦点

当activity获得焦点之后,activity是加载完毕的了,这个方法的技巧性比较强,很难想到。

1.     @Override

2.     publicvoid onWindowFocusChanged(boolean hasFocus) {

3.      // TODOAuto-generated method stub

4.     super.onWindowFocusChanged(hasFocus);

5.     if(hasFocus){

6.       showPopupWindow(getApplicationContext());

7.      }

8.     }

4 Surface的创建与有效性

当SurfaceView被实例化时,Surface并没有立即创建。相反,它是异步创建的。每当活动暂停或再次恢复而重新创建时,该Surface都将被销毁

只要Surface没有生效,我们就不能从SurfaceHolder中获取Canvas。不过,我们可以通过下面的语句来查看Surface是否已被创建:

boolean isCreated =surfaceHolder.getSurface().isValid();

如果该方法返回true,我们就可安全的锁定该Surface并通过接收到的Canvas来在其上进行绘制。我们必须绝对确保在调用SurfaceHolder.lockCanvas()之后再次解锁Surface,否则我们的活动可能会锁定手机。

参考

http://www.2cto.com/kf/201302/188341.html

5 Thread与SurfaceView

View组件由UI线程(主线程)所执行。如果需要迅速更新UI画面或UI画图需要较长时间,则需要使用SurfaceView。它可由后台线程(background thread)来执行,而View只能由UI(主)线程执行。SurfaceView内有高效的rendering机制,可以让后台线程快速刷新Surface的内容。

View ---> UI(主)线程

SurfaceView ---> 后台线程

参考

http://blog.csdn.net/myarrow/article/details/14223493

7 在找findViewById的过程中,由于开始忽略子类ViewGroup对View方法的重写,导致在View.class万行代码中陷入死循环

http://www.2cto.com/kf/201506/410705.html

8 viewRoot 的目的,实际上在什么地方渲染控件

每个activity有个window,window被windowmanager管理.

每个window都有decorview.

每个window都有ViewRoot.

绘制发起从ViewRoot.

事件传递发起冲ViewRoot.

绘制传递canvas, canvas来自surface.

http://blog.csdn.net/jacklam200/article/details/50038989

9 SurfaceView传递给底层NDK出错提示如下:

E/ExtMediaPlayer-JNI: env->IsInstanceOffails

E/MediaPlayer-JNI: JNIMediaPlayerFactory:bIsQCMediaPlayerPresent 0

private SurfaceHolder holder;

在查看的例子当中都是使用holder = this.getHolder();获取SurfaceHolder,

而没有通过参数的传递获取到SurfaceHolder变量

public void surfaceCreated(SurfaceHolder holder) {

// TODO Auto-generated method stub

holder = this.getHolder();

}

10 使用SurfaceView出现的崩溃信息

java.lang.RuntimeException: Could not read input channel file descriptors from parcel.

at android.view.InputChannel.nativeReadFromParcel(Native Method)

at android.view.InputChannel.readFromParcel(InputChannel.java:148)

at android.view.InputChannel$1.createFromParcel(InputChannel.java:39)

at android.view.InputChannel$1.createFromParcel(InputChannel.java:36)

at com.android.internal.view.InputBindResult.<init>(InputBindResult.java:68)

at com.android.internal.view.InputBindResult$1.createFromParcel(InputBindResult.java:112)

at com.android.internal.view.InputBindResult$1.createFromParcel(InputBindResult.java:109)

at com.android.internal.view.IInputMethodManager$Stub$Proxy.windowGainedFocus(IInputMethodManager.java:735)

at android.view.inputmethod.InputMethodManager.startInputInner(InputMethodManager.java:1232)

at android.view.inputmethod.InputMethodManager.onPostWindowFocus(InputMethodManager.java:1456)

at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3410)

at android.os.Handler.dispatchMessage(Handler.java:102)

at android.os.Looper.loop(Looper.java:148)

at android.app.ActivityThread.main(ActivityThread.java:5438)

at java.lang.reflect.Method.invoke(Native Method)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)

11 创建简单Surface测试例子

import android.app.Activity;

import android.content.Context;

import android.content.Intent;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Rect;

import android.os.Handler;

import android.os.Looper;

import android.os.MessageQueue;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.util.Log;

import android.view.Display;

import android.view.Surface;

import android.view.GestureDetector.OnGestureListener;

import android.view.MotionEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

import android.view.View;

public class MySurfaceView extends SurfaceView implements Callback{

int m_nWidth = 0;

int m_nHeight = 0;

static boolean m_isInitial = false;

static boolean m_Initialend = false;

public static boolean canTouch = true;

SurfaceHolder holder = null;

Surface m_surface = null;

Context m_context = null;

@SuppressWarnings("deprecation")

public MySurfaceView(Context context) {

super(context);

init(context);

}

public MySurfaceView(Context context, AttributeSet sets) {

super(context, sets);

init(context);

}

private void init(Context context)

{

m_context = context;

Display d = ((Activity) context).getWindowManager().getDefaultDisplay();

m_nWidth = d.getWidth();

m_nHeight = d.getHeight();

holder = getHolder();

holder.addCallback(this);

setZOrderOnTop(false);

}

@Override

public void surfaceChanged(SurfaceHolder surfaceholder, int arg1, int arg2,

int arg3) {

// TODO Auto-generated method stub

}

@Override

public void surfaceCreated(SurfaceHolder surfaceholder)

{

m_surface = surfaceholder.getSurface();

Thread newThread = new Thread(new Runnable()

{

@Override

public void run()

{

Canvas c = null;

try

{

synchronized (holder)

{

c = holder.lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。

c.drawColor(Color.BLUE);//设置画布背景颜色

Paint p = new Paint(); //创建画笔

p.setColor(Color.WHITE);

Rect r = new Rect(100, 50, 300, 250);

c.drawRect(r, p);

}

}

catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

finally

{

if(c!= null)

{

holder.unlockCanvasAndPost(c);//结束锁定画图,并提交改变。

}

}

}

});

newThread.start();

}

@Override

public void surfaceDestroyed(SurfaceHolder surfaceholder)

{

}

}

12 Surface渲染的时候黑屏一下,然后才显示界面

主要是Surface的背景是黑色的,如果渲染的时间过长,就可以明显的看到没有渲染完成的过程,其实这个时候可以设置一下Surface的背景,可以设置为柔和的颜色

时间: 2024-10-14 04:59:38

SurfaceView源码以及崩溃剖析的相关文章

ios局域网联机—苹果官方源码之WiTap剖析(一)(二)

http://www.it165.net/pro/html/201204/2094.html http://www.it165.net/pro/html/201204/2165.html 在过去的时间里,我一直在考虑的事情是,我该写一篇什么样的文章呢?之前的两篇文章都是先有问题,然后我才有目的的解决问题,现在我的困扰是,我不知道该写什么了呵呵.因为其实,大多数的问题,只要在网上搜索一下(google远比baidu要强得多),基本上都能找到解决的办法,已经有了许多相关方面的教程或参考资料了,我并不

Exchanger源码Android版剖析

Exchanger是一个针对线程可以结对交换元素的同步器.每条线程把某个对象作为参数调用exchange方法,与伙伴线程进行匹配,然后再函数返回的时接收伙伴的对象.另外,Exchanger内部实现采用的是无锁算法,能够大大提高多线程竞争下的吞吐量以及性能. 算法实现 基本方法是维持一个"槽"(slot),这个槽是保持交换对象的结点的引用,同时也是一个等待填满的"洞"(hole).如果一个即将到来的"占领"(occupying)线程发现槽为空,然后

MyBatis 源码篇-MyBatis-Spring 剖析

本章通过分析 mybatis-spring-x.x.x.jar Jar 包中的源码,了解 MyBatis 是如何与 Spring 进行集成的. Spring 配置文件 MyBatis 与 Spring 集成,在 Spring 配置文件中配置了数据源.SqlSessionFactory.自动扫描 MyBatis 中的 Mapper 接口.事务管理等,这部分内容都交由 Spring 管理.部分配置内容如下所示: <?xml version="1.0" encoding="U

django rest_fremework源码流程总体剖析

1. 序言 有如下django代码,视图层: 1 from django.http import HttpResponse 2 from rest_framework.views import APIView 3 class OrdersView(APIView): 4 def get(self , request , *args , **kwargs): 5 return HttpResponse('GET请求') 6 def post(self , request , *args , **k

SQLite源码目录结构剖析

研究的源码:sqlite-src-3081101 art 保存SQLite的形象图标 autoconf 提供config的配置文件 contrib doc ext mptest src test tool

mybatis源码级别深度剖析

mybatis 3.x源码深度解析与最佳实践 Mybatis源码解析优秀博文 原文地址:https://www.cnblogs.com/yixiu868/p/11295523.html

转:【Java集合源码剖析】TreeMap源码剖析

前言 本文不打算延续前几篇的风格(对所有的源码加入注释),因为要理解透TreeMap的所有源码,对博主来说,确实需要耗费大量的时间和经历,目前看来不大可能有这么多时间的投入,故这里意在通过于阅读源码对TreeMap有个宏观上的把握,并就其中一些方法的实现做比较深入的分析. 红黑树简介 TreeMap是基于红黑树实现的,这里只对红黑树做个简单的介绍,红黑树是一种特殊的二叉排序树,关于二叉排序树,参见:http://blog.csdn.net/ns_code/article/details/1982

(升级版)Spark从入门到精通(Scala编程、案例实战、高级特性、Spark内核源码剖析、Hadoop高端)

本课程主要讲解目前大数据领域最热门.最火爆.最有前景的技术——Spark.在本课程中,会从浅入深,基于大量案例实战,深度剖析和讲解Spark,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课程会涵盖Scala编程详解.Spark核心编程.Spark SQL和Spark Streaming.Spark内核以及源码剖析.性能调优.企业级案例实战等部分.完全从零起步,让学员可以一站式精通Spark企业级大数据开发,提升自己的职场竞争力,实现更好的升职或者跳槽,或者从j2ee等传统软件开发工程

tomcat集群实现源码级别剖析

随着互联网快速发展,各种各样供外部访问的系统越来越多且访问量越来越大,以前Web容器可以包揽接收-逻辑处理-响应整个请求生命周期的工作,现在为了构建让更多用户访问更强大的系统,人们通过不断地业务解耦.架构解耦将web容器的逻辑处理抽离交由其他中间件处理,例如缓存中间件.消息队列中间件.数据存储中间件等等.Web容器负责的工作可能越来越少,但是它确实必不可少的部分,它负责接收用户请求并分别调用各个服务最后响应.可以说目前最受欢迎的web容器是用Java写的tomcat小猫,由于生产上的tomcat