Surfaceview
This article is a secondary article of "[Android] surfaceview using instances.
This article consists of four parts. The first three parts are taken from the network, posted in the original article, and the first part is the sodino original code. Please read the first three parts carefully before reading Part 1 "4. Why is surfaceview able to refresh the interface in a non-UI thread? "
Bytes -------------------------------------------------------------------------------------------------------------------------
The following content is from the network.
1. Surface, window, view, surfaceview
Http://stackoverflow.com/questions/4576909/understanding-canvas-and-surface-concepts
A surface is an object holding pixels that are being composited to the screen.Every window you see on the screen (a dialog, your full-screen activity, the status bar) has its own surface that it draws in
To, and surface flinger renders these to the final display in their correct Z-order. A surface typically has more than one buffer (usually two) to do double-buffered rendering: The application can be drawing its next UI State while the surface flinger is compositing
The screen using the last buffer, without needing to wait for the application to finish drawing.
A window is basically like you think of a window on the desktop.It has a single surface in which the contents of the window is rendered. An application interacts with the window manager to create windows;
The window manager creates a surface for each window and gives it to the application for drawing. The application can draw whatever it wants in the surface; to the window manager it is just an opaque rectangle.
A view is an Interactive UI element inside of a window.A window has a single view hierarchy attached to it, which provides all of the behavior of the window. Whenever the window
Needs to be redrawn (such as because a view has invalidated itself), this is done into the window's surface. the surface is locked, which returns a canvas that can be used to draw into it. A draw traversal is done down the hierarchy, handing the canvas down
For each view to draw its part of the UI. once done, the surface is unlocked and posted so that the just drawn buffer is swapped to the foreground to then be composited to the screen by surface flinger.
A surfaceview is a special implementation of view that also creates its own dedicated surface for the application to directly draw(Outside of the normal view hierarchy, which otherwise must share
Single Surface for the window ). the way this works is simpler than you may have CT -- all surfaceview does is ask the window manager to create a new window, telling it to Z-order that window either immediately behind or in front of the surfaceview's window,
And positioning it to match where the surfaceview appears in the containing window. if the surface is being placed behind the main window (in Z order), surfaceview also fills its part of the main window with transparency so that
The surface can be seen.
2. Relationship between surface and canvas
Http://stackoverflow.com/questions/3370212/relationship-between-surface-and-canvas-android? SCSI = 1
A surface is a buffer. A canvas holds the drawing.
Views are not attached to the canvas nor the surface. The window is tied to a surface andThe viewroot asks the surface for a canvasThat is then used by the views to draw.
3. 7 questions
Http://www.mail-archive.com/android-framework@googlegroups.com/msg01901.html
> 1. What is the relationship between viewroot and View class.
The viewroot is the root of each view hierarchy. Like you said, there
Is one viewroot per window. The viewroot is responsible to handling
The layout and drawing of the view hierarchy. The view hierarchy is
Made of views and viewgroups. A viewgroup is a special view that can
Contain other views.
> 2. Is all view, its children's view and Their viewroot share the same
> Canvas for draw?
Yes, But that canvas might change on every drawing operation.
Viewroot acquires a canvas from the underlying surface and hands that
Canvas to the top-level view.
> 3. What is the relationship within view, canvas and surface. To my
> Thinking, every view will be attached a canvas and surface.
No, the views are not attached to the canvas nor the surface.
Window is tied to a surface and the viewroot asks the surface for
Canvas that is then used by the views to draw.
> 4. Canvas hold the bitmap for view, will the actual view drawn data will
> Be in canvas 'bitmap.
Yes.
> 5. After view draw its data to canvas, viewroot
> Will call surface. unlockcanvasandpost (canvas) to schedule
> Surfaceflinger: composesurfaces () which do the actually display
> Display panel.
Yes.
> 6. Where is the drawn data in canvas transfer to surface front buffer or
> Backbuffer? I cannot find the code to do that.
It's doneSurfaceflinger.
> 7. Do different views within the same viewroot share the same surface?
Yes, should t for surfaceviews.
The above is the source file copy.
Certificate ---------------------------------------------------------------------------------------------------------------------------------------
4. Why can surfaceview refresh the interface in a non-UI thread?
This problem is divided into two parts:
4.1 how does a common view refresh the interface?
View the viewroot. Java code. You can find that the interface refresh operation is completed in the method draw (Boolean fullredrawneeded.
Read the code carefully and find that the steps for refreshing the interface are the same as those for surfaceview. As follows:
a. canvas = surface.lockCanvas(dirty);b. do something draw actions...c. surface.unlockCanvasAndPost(canvas);
It can be seen that the core of the normal view and surfaceview interface refresh operations is: Request the canvas to the surface, execute the painting operation, and then submit it to the surface to display the screen again.
It can also be concluded that, compared with the UI thread, normal threads have no inherent limitations, and they all have the ability to refresh. Google engineers set obstacles in their code.
The next 2nd problems are to find out this obstacle.
Appendix: viewroot. Java source code
Http://www.netmite.com/android/mydroid/frameworks/base/core/java/android/view/ViewRoot.java
4.2 How does the refreshing code on the Interface determine whether the current thread is a UI thread?
In viewroot. Java, it is found that the view will be checkthread () when performing the following operations ().
Requestlayout () invalidatechild () requesttransparentregion () requestchildfocus () clearchildfocus () focusableviewavailable () recomputeviewattributes ()
That is, when UI operations such as re-layout, background change, and focus transfer are performed on the interface, the execution thread is checked for UI operation qualification.
The checkthread () code is found in viewrootimple. Java, as follows:
void checkThread() {if (mThread != Thread.currentThread()) {throw new CalledFromWrongThreadException("Only the original thread that created a view hierarchy can touch its views.");}}
Among them, mthread is final and has been assigned a value in the viewrootimple constructor.
That is, if you are qualified for UI operations, you must check with mthread.
Appendix: viewrootimple. JAVA Source Code address
Http://www.oschina.net/code/explore/android-4.0.1/core/java/android/view/ViewRootImpl.java
To sum up, surfaceview has its own proprietary surface, so asynchronous operations in common threads do not conflict with the painting layout of the UI thread; and it bypasses the checkthread () restriction, therefore, you can directly refresh the interface.
This article by sodino all, reprint please note the Source: http://blog.csdn.net/sodino/article/details/7709128
How does one determine whether the current thread is a UI thread by refreshing code on the "4.2 interface? "Checkthread () extension:
Cannot I update the interface in a non-UI thread? The answer is: as long as the non-UI thread runs faster than the UI thread, the interface can also be updated. The checkthread () vulnerability is exploited.
Note: In the checkthread () Judgment, the mthread is not limited to null. Therefore, only the interface update speed is fast enough. Before mthread is assigned a value, the checkthread () return value is still true, and non-UI threads can still update the interface.
Here is an example of using this vulnerability.
Create a standard Android project, set the ID of the existing textview in the default main. XML to "txtinfo", and change the oncreated () Code of the activity to the following:
Public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. main); Final progressdialog DLG = progressdialog. show (this, "title", "content"); Final textview txtinfo = (textview) findviewbyid(r.id.txt info); log. D ("android_lab", "thread [" + thread. currentthread (). getname () + "] ID:" + thread. currentthread (). GETID (); new thread () {public void run () {// No error T is reported here Xtinfo. settext ("Haha"); txtinfo. setbackgroundcolor (0xff123456); textview TXT = new textview (actlab. this); TXT. settext ("sodino"); linearlayout layout = (linearlayout) txtinfo. getparent (); layout. addview (txt); log. D ("android_lab", "thread [" + thread. currentthread (). getname () + "] ID:" + thread. currentthread (). GETID (); try {thread. sleep (5000l);} catch (interruptedexception e) {e. printstacktrace ();} // No error is reported here DL G. Cancel (); log. D ("android_lab", "After DLG. Cancel ()"); // an error is returned! Txtinfo. settext ("654321") ;}}. Start (); // runonuithread (action );}
After the script is run, the text in txtinfo has been changed from "Hello World" to "Haha" and the background color has changed. A textview is added. These operations are completed in non-UI threads.
Next, the thread sleep for 5 seconds. Then execute Cancel to display progressdialog, and the result is reversed to the day. The reason is unknown, but at least it proves that all the interface refreshes are not completed in the UI thread.
Then update txtinfo again. The result is an error and the prompt "only the original thread that created a view hierarchy can touch its views ."
Written by sodino
The above experiment also reminds everyone that you must carefully consider writing code. In addition, for special cases caused by code vulnerabilities, it is good to know that it is not allowed to be used in formal code programming.