package com.example.hello;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
private String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new CustomView1(this));
// setContentView(R.layout.activity_main);
// TextView mTextView01=(TextView)findViewById(R.id.textView1);
// mTextView01.setText("xiayu");
}
class CustomView1 extends View{
Paint paint;
public CustomView1(Context context) {
super(context);
paint = new Paint(); //设置一个笔刷大小是3的黄色的画笔
paint.setColor(Color.YELLOW);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(3);
}
//在这里我们将测试canvas提供的绘制图形方法
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
paint.setAntiAlias(true); //设置画笔为无锯齿
paint.setColor(Color.BLUE); //设置画笔颜色
canvas.drawColor(Color.WHITE); //白色背景
paint.setTextSize((float) 30.0); //设置字体大小
String str="Android应用程序开发 xiayu88"; //字符串
char[] ch={'H','e','l','l','o',' ','A','n','d','r','o','i','d'}; //字符数组
Log.d(TAG,Log.getStackTraceString(new Throwable()));
Log.e(TAG,"start canvas draw");
Log.e(TAG,"canvas.drawText:"+canvas);
canvas.drawText(str, 50, 200, paint); //绘制字符串
canvas.drawText(ch, 0, ch.length, 50, 300, paint); //绘制字符串
canvas.drawText(str+" API详解", 0, str.length()+6, 50, 400, paint);//绘制字符串
canvas.drawText(str, 7, str.length(), 50, 500, paint); //绘制字符串
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hello"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:hardwareAccelerated="true"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.hello.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
onDraw中的canvas是由hardwareAccelerated决定的类型。
hardwareAccelerated=true 的时候,canvas类型是android.view.GLES20RecordingCanvas 会调用 frameworks/base/libs/hwui/OpenGLRenderer.cpp
hardwareAccelerated=false 的时候,canvas类型是android.view.Surface$CompatibleCanvas@418ba290 直接调用android.graphics.Canvas.drawText
类关系
GLES20RecordingCanvas--> GLES20Canvas --> HardwareCanvas--> Canvas
CompatibleCanvas--> Canvas
堆栈信息
android:hardwareAccelerated="false
E/Canvas (23813): drawText2:Android应用程序开发 xiayu55
D/Canvas (23813): java.lang.Throwable
D/Canvas (23813): at android.graphics.Canvas.drawText(Canvas.java:1384)
D/Canvas (23813): at com.example.hello.MainActivity$CustomView1.onDraw(MainActivity.java:54)
D/Canvas (23813): at android.view.View.draw(View.java:14126)
D/Canvas (23813): at android.view.View.draw(View.java:14007)
D/Canvas (23813): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
D/Canvas (23813): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
D/Canvas (23813): at android.view.View.draw(View.java:14005)
D/Canvas (23813): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
D/Canvas (23813): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
D/Canvas (23813): at android.view.View.draw(View.java:14005)
D/Canvas (23813): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
D/Canvas (23813): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
D/Canvas (23813): at android.view.View.draw(View.java:14129)
D/Canvas (23813): at android.widget.FrameLayout.draw(FrameLayout.java:471)
D/Canvas (23813): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2231)
D/Canvas (23813): at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2490)
D/Canvas (23813): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2403)
D/Canvas (23813): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2247)
D/Canvas (23813): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1880)
D/Canvas (23813): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1008)
D/Canvas (23813): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5505)
D/Canvas (23813): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
D/Canvas (23813): at android.view.Choreographer.doCallbacks(Choreographer.java:562)
D/Canvas (23813): at android.view.Choreographer.doFrame(Choreographer.java:532)
D/Canvas (23813): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
D/Canvas (23813): at android.os.Handler.handleCallback(Handler.java:730)
D/Canvas (23813): at android.os.Handler.dispatchMessage(Handler.java:92)
D/Canvas (23813): at android.os.Looper.loop(Looper.java:217)
D/Canvas (23813): at android.app.ActivityThread.main(ActivityThread.java:5225)
D/Canvas (23813): at java.lang.reflect.Method.invokeNative(Native Method)
D/Canvas (23813): at java.lang.reflect.Method.invoke(Method.java:525)
D/Canvas (23813): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
D/Canvas (23813): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
D/Canvas (23813): at dalvik.system.NativeStart.main(Native Method)
android:hardwareAccelerated=true
在apk打的堆栈
D/GLES20Canvas(11422): java.lang.Throwable
D/GLES20Canvas(11422): at android.view.GLES20Canvas.drawDisplayList(GLES20Canvas.java:396)
D/GLES20Canvas(11422): at android.view.GLES20RecordingCanvas.drawDisplayList(GLES20RecordingCanvas.java:148)
D/GLES20Canvas(11422): at android.view.View.draw(View.java:14011)
D/GLES20Canvas(11422): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
D/GLES20Canvas(11422): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
D/GLES20Canvas(11422): at android.view.View.getDisplayList(View.java:13015)
D/GLES20Canvas(11422): at android.view.View.getDisplayList(View.java:13062)
D/GLES20Canvas(11422): at android.view.View.draw(View.java:13839)
D/GLES20Canvas(11422): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
D/GLES20Canvas(11422): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
D/GLES20Canvas(11422): at android.view.View.getDisplayList(View.java:13015)
D/GLES20Canvas(11422): at android.view.View.getDisplayList(View.java:13062)
D/GLES20Canvas(11422): at android.view.View.draw(View.java:13839)
D/GLES20Canvas(11422): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
D/GLES20Canvas(11422): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
D/GLES20Canvas(11422): at android.view.View.draw(View.java:14129)
D/GLES20Canvas(11422): at android.widget.FrameLayout.draw(FrameLayout.java:471)
D/GLES20Canvas(11422): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2231)
D/GLES20Canvas(11422): at android.view.View.getDisplayList(View.java:13020)
D/GLES20Canvas(11422): at android.view.View.getDisplayList(View.java:13062)
D/GLES20Canvas(11422): at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1411)
D/GLES20Canvas(11422): at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1359)
D/GLES20Canvas(11422): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2375)
D/GLES20Canvas(11422): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2247)
D/GLES20Canvas(11422): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1880)
D/GLES20Canvas(11422): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1008)
D/GLES20Canvas(11422): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5505)
D/GLES20Canvas(11422): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
D/GLES20Canvas(11422): at android.view.Choreographer.doCallbacks(Choreographer.java:562)
D/GLES20Canvas(11422): at android.view.Choreographer.doFrame(Choreographer.java:532)
D/GLES20Canvas(11422): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
D/GLES20Canvas(11422): at android.os.Handler.handleCallback(Handler.java:730)
D/GLES20Canvas(11422): at android.os.Handler.dispatchMessage(Handler.java:92)
D/GLES20Canvas(11422): at android.os.Looper.loop(Looper.java:217)
D/GLES20Canvas(11422): at android.app.ActivityThread.main(ActivityThread.java:5225)
D/GLES20Canvas(11422): at java.lang.reflect.Method.invokeNative(Native Method)
D/GLES20Canvas(11422): at java.lang.reflect.Method.invoke(Method.java:525)
D/GLES20Canvas(11422): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
D/GLES20Canvas(11422): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
D/GLES20Canvas(11422): at dalvik.system.NativeStart.main(Native Method)
在jni层下的c++ log
0 /system/lib/libhwui.so
android::uirenderer::OpenGLRenderer::drawText(char const*, int, int, float, float, float const*, SkPaint*, float, android::uirenderer::DrawOpMode)
/home/CORPUSERS/xp013185/my_repo/new_dsds/frameworks/base/libs/hwui/OpenGLRenderer.cpp:2871
1 /system/lib/libhwui.so
android::uirenderer::DrawTextOp::multiDraw(android::uirenderer::OpenGLRenderer&, android::uirenderer::Rect&, android::Vector<android::uirenderer::DrawOp*> const&, android::uirenderer::Rect const&)
/home/CORPUSERS/xp013185/my_repo/new_dsds/frameworks/base/libs/hwui/DisplayListOp.h:1328
2 /system/lib/libhwui.so
android::uirenderer::MergingDrawBatch::replay(android::uirenderer::OpenGLRenderer&, android::uirenderer::Rect&, int)
/home/CORPUSERS/xp013185/my_repo/new_dsds/frameworks/base/libs/hwui/DeferredDisplayList.cpp:206
3 /system/lib/libhwui.so
replayBatchList
/home/CORPUSERS/xp013185/my_repo/new_dsds/frameworks/base/libs/hwui/DeferredDisplayList.cpp:529
4 /system/lib/libhwui.so
android::uirenderer::OpenGLRenderer::drawDisplayList(android::uirenderer::DisplayList*, android::uirenderer::Rect&, int)
/home/CORPUSERS/xp013185/my_repo/new_dsds/frameworks/base/libs/hwui/OpenGLRenderer.cpp:1956
5 /system/lib/libandroid_runtime.so
android_view_GLES20Canvas_drawDisplayList
/home/CORPUSERS/xp013185/my_repo/new_dsds/frameworks/base/core/jni/android_view_GLES20Canvas.cpp:733
6 /system/lib/libdvm.so
dvmPlatformInvoke
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/arch/arm/CallEABI.S:258
7 /system/lib/libdvm.so
dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/Jni.cpp:1218
8 /system/lib/libdvm.so
dvmCheckCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/CheckJni.cpp:145
9 /system/lib/libdvm.so
dalvik_mterp
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/mterp/out/InterpAsm-armv7-a-neon.S:16314
10 /system/lib/libdvm.so
dvmInterpret(Thread*, Method const*, JValue*)
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/interp/Interp.cpp:1956
11 /system/lib/libdvm.so
dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/interp/Stack.cpp:737
12 /system/lib/libdvm.so
Dalvik_java_lang_reflect_Method_invokeNative
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/native/java_lang_reflect_Method.cpp:101
13 /system/lib/libdvm.so
dalvik_mterp
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/mterp/out/InterpAsm-armv7-a-neon.S:16314
14 /system/lib/libdvm.so
dvmInterpret(Thread*, Method const*, JValue*)
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/interp/Interp.cpp:1956
15 /system/lib/libdvm.so
dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/interp/Stack.cpp:526
16 /system/lib/libdvm.so
CallStaticVoidMethodV
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/Jni.cpp:2155
17 /system/lib/libdvm.so
Check_CallStaticVoidMethodV
/home/CORPUSERS/xp013185/my_repo/new_dsds/dalvik/vm/CheckJni.cpp:1690
18 /system/lib/libandroid_runtime.so
_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)
/home/CORPUSERS/xp013185/my_repo/new_dsds/libnativehelper/include/nativehelper/jni.h:779
19 /system/lib/libandroid_runtime.so
android::AndroidRuntime::start(char const*, char const*)
/home/CORPUSERS/xp013185/my_repo/new_dsds/frameworks/base/core/jni/AndroidRuntime.cpp:886