精华内容
下载资源
问答
  • Android开发笔记(序)写在前面的目录

    万次阅读 多人点赞 2015-11-24 14:36:06
    因此博主就想,入门的东西咱就不写了,人不能老停留入门上;其次是想拾缺补漏,写写虽然小众却又用得着的东西;另外就是想以实用为主,不求大而全,但求小而精;还有就是有的知识点是java的,只是Android开发也会...

     

    知识点分类

    一方面写写自己走过的弯路掉进去的坑,避免以后再犯;另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平。因此博主就想,入门的东西咱就不写了,人不能老停留在入门上;其次是想拾缺补漏,写写虽然小众却又用得着的东西;另外就是想以实用为主,不求大而全,但求小而精;还有就是有的知识点是java的,只是Android开发也会经常遇上,所以蛮记下来。个人的经验总结,难免有遗漏谬误之处,希望网友们不吝指教。

    为了找起来方便,暂且分为七大类:显示、存储、通信、发布与调优、进阶用法、与时俱进、继续精进。

    显示又分为八块:屏幕、文本、图形、简单控件、自定义视图、动画、窗口、复杂控件;

    存储分为六块:资源、内存、键值对、数据库、文件、网络存储;

    通信分作六块:组件通信、事件通信、多线程通信、跨进程通信、设备通信、网络通信;

    发布与调优分为五块:打包、安全、性能、健壮、兼容;

    进阶用法分为六块:java细节、设计模式、图像处理、高级控件、第三方sdk、开发者工具;

    与时俱进分为六块:新版控件、多媒体开发、高级动画、行为协调、页面切换、花样输入;

    继续精进分为六块:人工智能、混合开发、三维动画、物联网、屏幕特效、视频加工;

    本系列的开发笔记已有部分文章整理成书出版,有兴趣的读者可移步前往《Android Studio开发实战 从零基础到App上线》

     

    目录( 共7卷41章167节)

     

    第一卷 显示 共8章32节

    第一章 屏幕
    Android开发笔记(一)像素的单位
    Android开发笔记(二)颜色的使用
    Android开发笔记(三)屏幕分辨率
    第二章 文本
    Android开发笔记(四)字符串格式化
    Android开发笔记(五)日期的处理
    Android开发笔记(六)可变字符串
    第三章 图形
    Android开发笔记(七)初识Drawable
    Android开发笔记(八)神奇的shape
    Android开发笔记(九)特别的.9图片
    Android开发笔记(十)常用的图片加工操作
    第十二章 简单控件
    Android开发笔记(三十五)页面布局视图
    Android开发笔记(三十六)展示类控件
    Android开发笔记(三十七)按钮类控件
    Android开发笔记(三十八)列表类视图
    第四章 自定义视图
    Android开发笔记(十一)自定义视图的构造方法
    Android开发笔记(十二)测量尺寸与下拉刷新
    Android开发笔记(十三)视图绘制的几个方法
    第五章 动画效果
    Android开发笔记(十四)圆弧进度动画
    Android开发笔记(十五)淡入淡出动画
    Android开发笔记(十六)秋千摇摆动画
    Android开发笔记(十七)GIF动画的实现
    Android开发笔记(十八)书籍翻页动画
    第十九章 窗口
    Android开发笔记(六十五)多样的菜单
    Android开发笔记(六十六)自定义对话框
    Android开发笔记(一百一十八)自定义悬浮窗
    Android开发笔记(一百二十一)列表弹窗PopupMenu和ListPopupWindow
    Android开发笔记(一百二十七)活用提示窗Toast和Snackbar
    第六章 复杂控件
    Android开发笔记(十九)底部标签栏
    Android开发笔记(二十)顶部导航栏
    Android开发笔记(二十一)横幅轮播页
    Android开发笔记(二十二)瀑布流网格
    Android开发笔记(二十三)文件对话框
     

    第二卷 存储 共6章18节

    第七章 资源
    Android开发笔记(二十四)res目录的结构与配置
    Android开发笔记(二十五)assets目录的文件读取
    第八章 内存
    Android开发笔记(二十六)Java的容器类
    Android开发笔记(二十七)对象序列化
    Android开发笔记(二十八)利用Application实现内存读写
    第九章 键值对
    Android开发笔记(二十九)使用SharedPreferences存取数据
    Android开发笔记(八十四)使用Properties读写属性值
    第十章 数据库
    Android开发笔记(三十)SQLite数据库基础操作
    Android开发笔记(三十一)SQLite游标及其数据结构
    Android开发笔记(八十五)手机数据库Realm
    第十一章 文件
    Android开发笔记(三十二)文件基础操作
    Android开发笔记(三十三)文本文件和图片文件的读写
    Android开发笔记(三十四)Excel文件的读写
    Android开发笔记(一百四十)Word文件的读取与显示
    Android开发笔记(一百四十一)读取PPT和PDF文件
    第三十章 网络存储
    Android开发笔记(六十一)文件下载管理DownloadManager
    Android开发笔记(一百零九)利用网盘实现云存储
    Android开发笔记(一百一十)使用http框架上传文件
     

    第三卷 通信 共6章28节

    第十三章 组件通信
    Android开发笔记(三十九)Activity的生命周期
    Android开发笔记(四十)组件通讯工具Intent
    Android开发笔记(四十一)Service的生命周期
    Android开发笔记(四十二)Broadcast的生命周期
    Android开发笔记(六十七)嵌入页面的碎片
    第十四章 事件通信
    Android开发笔记(四十三)点击事件
    Android开发笔记(四十四)动态UI事件
    Android开发笔记(四十五)手势事件
    Android开发笔记(四十六)手机相关事件
    第十五章 多线程通信
    Android开发笔记(四十七)Runnable接口实现多线程
    Android开发笔记(四十八)Thread类实现多线程
    Android开发笔记(四十九)异步任务处理AsyncTask
    Android开发笔记(五十)定时器AlarmManager
    Android开发笔记(一百四十三)任务调度JobScheduler
    第十六章 跨进程通信
    Android开发笔记(五十一)通过Messenger实现进程间通信
    Android开发笔记(五十二)通知推送Notification
    Android开发笔记(五十三)远程接口调用AIDL
    Android开发笔记(五十四)数据共享接口ContentProvider
    第十七章 设备通信
    Android开发笔记(五十五)手机设备基本操作
    Android开发笔记(五十六)摄像头拍照
    Android开发笔记(五十七)录像录音与播放
    Android开发笔记(五十八)铃声与震动
    Android开发笔记(五十九)巧用传感器
    第十八章 网络通信
    Android开发笔记(六十)网络的检测与连接
    Android开发笔记(六十二)HTTP数据格式的解析
    Android开发笔记(六十三)HTTP访问的通信方式
    Android开发笔记(六十四)网页加载与JS调用
    Android开发笔记(一百一十一)聊天室中的Socket通信
     

    第四卷 发布与调优 共5章20节

    第二十章 打包
    Android开发笔记(六十八)工程库打包
    Android开发笔记(六十九)JNI实战
    Android开发笔记(七十)反编译初步
    第二十一章 安全
    Android开发笔记(七十一)区分开发模式和上线模式
    Android开发笔记(七十二)数据加密算法
    Android开发笔记(七十三)代码混淆与反破解
    第二十二章 性能
    Android开发笔记(七十四)布局文件优化
    Android开发笔记(七十五)内存泄漏的处理
    Android开发笔记(七十六)线程池管理
    Android开发笔记(七十七)图片缓存算法
    Android开发笔记(一百一十七)app省电方略
    第二十三章 健壮
    Android开发笔记(七十八)异常容错处理
    Android开发笔记(七十九)资源与权限校验
    Android开发笔记(八十)运行状态检查
    Android开发笔记(一百五十八)运行时动态授权管理
    第二十四章 兼容
    Android开发笔记(八十一)屏幕规格适配
    Android开发笔记(八十二)SDK版本兼容
    Android开发笔记(八十三)多语言支持
    Android开发笔记(一百二十八)手机制式适配
    Android开发笔记(一百六十)休眠模式下的定时器控制
     

    第五卷 进阶用法 共6章28节

    第二十五章 java细节
    Android开发笔记(八十六)几个特殊的类
    Android开发笔记(八十七)几个修饰关键字
    Android开发笔记(八十八)同步与加锁
    第二十六章 设计模式
    Android开发笔记(八十九)单例模式
    Android开发笔记(九十)建造者模式
    Android开发笔记(九十一)工厂模式
    Android开发笔记(九十二)策略模式
    Android开发笔记(九十三)装饰模式
    第二十七章 图像处理
    Android开发笔记(九十四)图片的基本加工
    Android开发笔记(九十五)自定义Drawable
    Android开发笔记(九十七)图片的特效处理
    Android开发笔记(九十八)往图片添加部件
    Android开发笔记(一百二十九)使用变换图形
    第二十八章 高级控件
    Android开发笔记(九十九)圆形转盘
    Android开发笔记(一百)折叠式列表
    Android开发笔记(一百零一)滑出式菜单
    Android开发笔记(一百零二)统计图表
    Android开发笔记(一百零八)智能语音
    第二十九章 第三方sdk
    Android开发笔记(一百零三)地图与定位SDK
    Android开发笔记(一百零四)消息推送SDK
    Android开发笔记(一百零五)社会化分享SDK
    Android开发笔记(一百零六)支付缴费SDK
    Android开发笔记(一百零七)统计分析SDK
    第三十一章 开发者工具
    Android开发笔记(一百一十二)开发工具
    Android开发笔记(一百一十三)测试工具
    Android开发笔记(一百一十四)发布工具
    Android开发笔记(一百一十五)设计工具
    Android开发笔记(一百一十六)网络学习资源
     

    第六卷 与时俱进 共6章25节

    第三十二章 新版控件
    Android开发笔记(一百一十九)工具栏Toolbar
    Android开发笔记(一百二十)两种侧滑布局
    Android开发笔记(一百二十二)循环器视图RecyclerView
    Android开发笔记(一百二十三)下拉刷新布局SwipeRefreshLayout
    Android开发笔记(一百三十三)导航视图NavigationView
    第三十三章 多媒体开发
    Android开发笔记(一百二十四)自定义相册
    Android开发笔记(一百二十五)自定义视频播放器
    Android开发笔记(一百二十六)自定义音乐播放器
    Android开发笔记(一百三十)截图和录屏
    第三十四章 高级动画
    Android开发笔记(九十六)集合动画与属性动画
    Android开发笔记(一百三十一)水波图形与水波动画
    Android开发笔记(一百三十二)矢量图形与矢量动画
    Android开发笔记(一百四十五)仿应用宝的垃圾清理动画
    第三十五章 行为协调
    Android开发笔记(一百三十四)协调布局CoordinatorLayout
    Android开发笔记(一百三十五)应用栏布局AppBarLayout
    Android开发笔记(一百三十六)可折叠工具栏布局CollapsingToolbarLayout
    Android开发笔记(一百三十七)自定义行为Behavior
    Android开发笔记(一百四十四)高仿支付宝的头部伸缩动画
    第三十六章 页面切换
    Android开发笔记(一百三十九)可定制可滑动的标签栏
    Android开发笔记(一百四十二)平滑翻页的书籍浏览
    Android开发笔记(一百四十七)标签布局TabLayout
    第三十七章 花样输入
    Android开发笔记(一百三十八)文本输入布局TextInputLayout
    Android开发笔记(一百四十六)仿支付宝的支付密码输入框
    Android开发笔记(一百四十八)自定义输入法软键盘
    Android开发笔记(一百四十九)约束布局ConstraintLayout
     

    第七卷 继续精进 共4章16节

    第三十八章 人工智能
    Android开发笔记(一百五十)自动识别验证码图片
    第三十九章 混合开发
    Android开发笔记(一百五十一)WebView与JavaScript交互的四种形式
    Android开发笔记(一百五十二)H5通过WebView上传图片
    Android开发笔记(一百六十六)H5通过WebView录像上传
    第四十章 三维动画
    Android开发笔记(一百五十三)OpenGL绘制三维图形的流程
    Android开发笔记(一百五十四)OpenGL的画笔工具GL10
    Android开发笔记(一百五十五)利用GL10描绘点、线、面
    Android开发笔记(一百五十六)通过渲染纹理展示地球仪
    Android开发笔记(一百五十七)使用OpenGL实现翻书动画
    第四十一章 物联网
    Android开发笔记(一百六十一)NFC近场通信
    Android开发笔记(一百六十二)蓝牙设备的连接与配对
    Android开发笔记(一百六十五)利用红外发射遥控电器
    第四十二章 屏幕特效
    Android开发笔记(一百五十九)Android7.0的分屏模式
    Android开发笔记(一百六十三)高仿京东的沉浸式状态栏
    Android开发笔记(一百六十四)仿京东首页的下拉刷新
    Android开发笔记(一百六十七)Android8.0的画中画模式

    待续

     

     

    索引

    下面是本系列笔记用到的知识点,分门别类整理一下,方便日后查阅。

     

    java类

    名称类名出处
    基本数据类型String、Integer、Double、BigDecimalAndroid开发笔记(四)字符串格式化
    格式化工具Formatter、DecimalFormat、NumberFormatAndroid开发笔记(四)字符串格式化
    样式、匹配器Pattern、MatcherAndroid开发笔记(四)字符串格式化
    日期、日历Date、SimpleDateFormat、CalendarAndroid开发笔记(五)日期的处理
    向量、队列、链表Set/HashSet、ArrayList、LinkedListAndroid开发笔记(二十六)Java的容器类
    矢量、栈Vector、StackAndroid开发笔记(二十六)Java的容器类
    映射、哈希表Map/HashMap、HashtableAndroid开发笔记(二十六)Java的容器类
    迭代器IteratorAndroid开发笔记(二十六)Java的容器类
    序列化结构SerializableAndroid开发笔记(二十七)对象序列化
    文件FileAndroid开发笔记(三十二)文件基础操作
    文件流FileOutputStream、FileInputStreamAndroid开发笔记(三十三)文本文件和图片文件的读写
    缓存流BufferedOutputStream、BufferedInputStreamAndroid开发笔记(三十三)文本文件和图片文件的读写
    任务RunnableAndroid开发笔记(四十七)Runnable接口实现多线程
    线程ThreadAndroid开发笔记(四十八)Thread类实现多线程
    定时器Timer、TimerTaskAndroid开发笔记(五十)定时器AlarmManager
    反射reflectAndroid开发笔记(六十)网络的检测与连接
    xml解析XmlPullParser、dom、sax、SAXParserAndroid开发笔记(六十二)HTTP数据格式的解析
    输入输出流InputStream、OutputStreamAndroid开发笔记(六十三)HTTP访问的通信方式
    http连接HttpURLConnection、HttpClientAndroid开发笔记(六十三)HTTP访问的通信方式
    URL编码和解码URLEncoder、URLDecoderAndroid开发笔记(七十二)数据加密算法
    BASE64编码和解码BASE64Encoder、BASE64DecoderAndroid开发笔记(七十二)数据加密算法
    加密算法Cipher、KeyGenerator、SecretKey、MessageDigestAndroid开发笔记(七十二)数据加密算法
    线程池Executors、ThreadPoolExecutorAndroid开发笔记(七十六)线程池管理
    定时器线程池ScheduledExecutorServiceAndroid开发笔记(七十六)线程池管理
    异常ExceptionAndroid开发笔记(七十八)异常容错处理
    键值对属性PropertiesAndroid开发笔记(八十四)使用Properties读写属性值
    加锁ReentrantLock、ReentrantReadWriteLockAndroid开发笔记(八十八)同步与加锁
    字符串建造者StringBuilderAndroid开发笔记(九十)建造者模式
    数组、容器组Arrays、CollectionsAndroid开发笔记(九十二)策略模式
    数学函数MathAndroid开发笔记(九十九)圆形转盘
    套接字、网络地址Socket、SocketServer、InetAddressAndroid开发笔记(一百一十一)聊天室中的Socket通信

     

     

     

    Android控件类

     

     

     

    名称类名出处
    颜色ColorAndroid开发笔记(二)颜色的使用
    可变字符串Spannable、SpannableStringAndroid开发笔记(六)可变字符串
    风格区域、URL区域StyleSpan、URLSpanAndroid开发笔记(六)可变字符串
    状态图形Drawable、StateListDrawableAndroid开发笔记(七)初识Drawable
    形状图形ShapeDrawableAndroid开发笔记(八)神奇的shape
    点九图形NinePatchDrawableAndroid开发笔记(九)特别的.9图片
    画布、画笔Canvas、PaintAndroid开发笔记(十三)视图绘制的几个方法
    透明度动画AlphaAnimationAndroid开发笔记(十五)淡入淡出动画
    过渡图形TransitionDrawableAndroid开发笔记(十五)淡入淡出动画
    旋转动画RotateAnimationAndroid开发笔记(十六)秋千摇摆动画
    帧动画AnimationDrawableAndroid开发笔记(十七)GIF动画的实现
    梯度图形GradientDrawableAndroid开发笔记(十八)书籍翻页动画
    标签页TabHost、TabWidgetAndroid开发笔记(十九)底部标签栏TabBar
    标题栏ActionBarAndroid开发笔记(二十)顶部导航栏ActionBar
    溢出菜单OverflowMenuAndroid开发笔记(二十)顶部导航栏ActionBar
    导航栏NavigationAndroid开发笔记(二十)顶部导航栏ActionBar
    定制视图CustomViewAndroid开发笔记(二十)顶部导航栏ActionBar
    搜索视图SearchViewAndroid开发笔记(二十)顶部导航栏ActionBar
    翻页视图ViewPagerAndroid开发笔记(二十一)横幅轮播页Banner
    翻页标题PagerTabStrip、PagerTitleStripAndroid开发笔记(二十一)横幅轮播页Banner
    飞掠视图ViewFlipperAndroid开发笔记(二十一)横幅轮播页Banner
    翻页适配器PagerAdapter、FragmentStatePagerAdapterAndroid开发笔记(二十一)横幅轮播页Banner
    日期和时间控件DatePicker、TimePickerAndroid开发笔记(二十三)文件对话框FileDialog
    对话框碎片DialogFragmentAndroid开发笔记(二十三)文件对话框FileDialog
    布局视图LinearLayout、RelativeLayout、FrameLayoutAndroid开发笔记(三十五)页面布局视图
    滚动视图ScrollView、HorizontalScrollViewAndroid开发笔记(三十五)页面布局视图
    基本视图View、ViewGroupAndroid开发笔记(三十六)展示类控件
    文本框、图像视图TextView、EditText、ImageViewAndroid开发笔记(三十六)展示类控件
    按钮、图像按钮Button、ImageButtonAndroid开发笔记(三十七)按钮类控件
    复合按钮CompoundButtonAndroid开发笔记(三十七)按钮类控件
    复选框、开关、单选框CheckBox、Switch、RadioGroup、RadioButtonAndroid开发笔记(三十七)按钮类控件
    下拉框、列表视图、网格视图Spinner、ListView、GridViewAndroid开发笔记(三十八)列表类视图
    适配器视图AdapterView、AdapterAndroid开发笔记(三十八)列表类视图
    基本适配器BaseAdapter、ArrayAdapter、SimpleAdapterAndroid开发笔记(三十八)列表类视图
    自动完成编辑框AutoCompleteTextViewAndroid开发笔记(四十四)动态UI事件
    进度条、进度对话框ProgressBar、ProgressDialogAndroid开发笔记(四十九)异步任务处理AsyncTask
    远程视图RemoteViewsAndroid开发笔记(五十二)通知推送Notification
    表面视图SurfaceView、SurfaceHolderAndroid开发笔记(五十六)摄像头拍照
    媒体录制器、媒体播放器MediaRecorder、MediaPlayerAndroid开发笔记(五十七)录像录音与播放
    拖动条SeekBarAndroid开发笔记(五十八)铃声与震动
    网页视图WebView、WebSettingsAndroid开发笔记(六十四)网页加载与JS调用
    网页视图客户端WebViewClient、WebChromeClientAndroid开发笔记(六十四)网页加载与JS调用
    菜单、选项菜单、上下文菜单Menu、OptionsMenu、ContextMenuAndroid开发笔记(六十五)多样的菜单
    弹窗PopupWindowAndroid开发笔记(六十五)多样的菜单
    对话框AlertDialog、DialogAndroid开发笔记(六十六)自定义对话框
    碎片FragmentAndroid开发笔记(六十七)嵌入页面的碎片
    占位视图ViewStubAndroid开发笔记(七十四)布局文件优化
    风格、主题Style、ThemeAndroid开发笔记(七十四)布局文件优化
    汉字转拼音HanziToPinyinAndroid开发笔记(八十三)多语言支持
    位图Bitmap、BitmapDrawableAndroid开发笔记(九十四)图片的基本加工
    集合动画AnimationSetAndroid开发笔记(九十六)集合动画与属性动画
    属性动画ObjectAnimator、AnimatorSetAndroid开发笔记(九十六)集合动画与属性动画
    路径、矩阵Path、MatrixAndroid开发笔记(九十九)圆形转盘
    折叠列表视图ExpandableListView、ExpandableListAdapterAndroid开发笔记(一百)折叠式列表
    列表碎片ListFragmentAndroid开发笔记(一百零一)滑出式菜单
    文字转语音TextToSpeechAndroid开发笔记(一百零八)语音识别与合成
    参数设置碎片PreferenceFragmentAndroid开发笔记(一百零八)语音识别与合成
    工具栏、搜索框Toolbar、SearchViewAndroid开发笔记(一百一十九)工具栏Toolbar
    侧滑布局DrawerLayout、SlidingPaneLayoutAndroid开发笔记(一百二十)两种侧滑布局
    弹出菜单、列表弹窗PopupMenu、ListPopupWindowAndroid开发笔记(一百二十一)列表弹窗
    循环器视图RecyclerViewAndroid开发笔记(一百二十二)循环器视图
    下拉刷新布局SwipeRefreshLayoutAndroid开发笔记(一百二十三)下拉刷新布局
    画廊GalleryAndroid开发笔记(一百二十四)自定义相册
    图像切换器ImageSwitcherAndroid开发笔记(一百二十四)自定义相册
    调色板PaletteAndroid开发笔记(一百二十四)自定义相册
    卡片视图CardViewAndroid开发笔记(一百二十四)自定义相册
    视频视图VideoViewAndroid开发笔记(一百二十五)自定义视频播放器
    媒体控制条MediaControllerAndroid开发笔记(一百二十五)自定义视频播放器
    音频录制AudioRecordAndroid开发笔记(一百二十六)自定义音乐播放器
    音轨播放AudioTrackAndroid开发笔记(一百二十六)自定义音乐播放器
    声音池SoundPoolAndroid开发笔记(一百二十六)自定义音乐播放器
    提示窗Toast、SnackbarAndroid开发笔记(一百二十七)活用提示窗Toast和Snackbar
    裁剪图形ClipDrawableAndroid开发笔记(一百二十九)使用变换图形
    缩放图形ScaleDrawableAndroid开发笔记(一百二十九)使用变换图形
    旋转图形RotateDrawableAndroid开发笔记(一百二十九)使用变换图形
    水波图形RippleDrawableAndroid开发笔记(一百三十一)水波图形与水波动画
    矢量图形VectorDrawableAndroid开发笔记(一百三十二)矢量图形与矢量动画
    矢量动画AnimatedVectorDrawableAndroid开发笔记(一百三十二)矢量图形与矢量动画
    导航视图NavigationViewAndroid开发笔记(一百三十三)导航视图NavigationView
    协调布局CoordinatorLayoutAndroid开发笔记(一百三十四)协调布局CoordinatorLayout
    悬浮按钮FloatingActionButtonAndroid开发笔记(一百三十四)协调布局CoordinatorLayout
    底部弹窗BottomSheetBehaviorAndroid开发笔记(一百三十四)协调布局CoordinatorLayout
    应用栏布局AppBarLayoutAndroid开发笔记(一百三十五)应用栏布局AppBarLayout
    嵌套滚动视图NestedScrollViewAndroid开发笔记(一百三十五)应用栏布局AppBarLayout
    可折叠工具栏布局CollapsingToolbarLayoutAndroid开发笔记(一百三十六)可折叠工具栏布局CollapsingToolbarLayout
    文本输入布局TextInputLayoutAndroid开发笔记(一百三十八)文本输入布局TextInputLayout
    文本输入编辑框TextInputEditTextAndroid开发笔记(一百三十八)文本输入布局TextInputLayout
    碎片标签组FragmentTabHostAndroid开发笔记(一百三十九)可定制可滑动的标签栏
    栈视图StackViewAndroid开发笔记(一百四十二)平滑翻页的书籍浏览
    标签布局TabLayoutAndroid开发笔记(一百四十七)标签布局TabLayout
    约束布局ConstraintLayoutAndroid开发笔记(一百四十九)约束布局ConstraintLayout
    OpenGL表面视图GLSurfaceViewAndroid开发笔记(一百五十三)OpenGL绘制三维图形的流程
    OpenGL画笔GL10Android开发笔记(一百五十四)OpenGL的画笔工具GL10

     

     

     

    Android管理类

     

     

     

    名称类名出处
    窗口管理WindowManagerAndroid开发笔记(三)屏幕分辨率
    显示信息Display、DisplayMetricsAndroid开发笔记(三)屏幕分辨率
    标签页面TabActivityAndroid开发笔记(十九)底部标签栏TabBar
    页面组ActivityGroupAndroid开发笔记(十九)底部标签栏TabBar
    碎片页面FragmentActivityAndroid开发笔记(十九)底部标签栏TabBar
    资源管理ResourcesAndroid开发笔记(二十四)res目录的结构与配置
    资产管理AssetManagerAndroid开发笔记(二十五)assets目录下的文件读取
    打包结构ParcelableAndroid开发笔记(二十七)对象序列化
    应用ApplicationAndroid开发笔记(二十八)利用Application实现内存读写
    共享参数SharedPreferencesAndroid开发笔记(二十九)使用SharedPreferences存取数据
    SQLite数据库SQLiteDatabase、SQLiteOpenHelperAndroid开发笔记(三十)SQLite数据库基础操作
    游标ContentValues、CursorAndroid开发笔记(三十一)SQLite游标及其数据结构
    环境管理EnvironmentAndroid开发笔记(三十二)文件基础操作
    输入法管理InputMethodManagerAndroid开发笔记(三十六)展示类控件
    列表页面ListActivityAndroid开发笔记(三十八)列表类视图
    页面ActivityAndroid开发笔记(三十九)Activity的生命周期
    意图、意图过滤器Intent、IntentFilterAndroid开发笔记(四十)组件通讯工具Intent
    包裹BundleAndroid开发笔记(四十)组件通讯工具Intent
    服务、异步服务Service、IntentServiceAndroid开发笔记(四十一)Service的生命周期
    广播、广播接收器Broadcast、BroadcastReceiverAndroid开发笔记(四十二)Broadcast的生命周期
    手势事件MotionEventAndroid开发笔记(四十五)手势事件
    手势检测器GestureDetectorAndroid开发笔记(四十五)手势事件
    滚动器ScrollerAndroid开发笔记(四十五)手势事件
    定位管理LocationManager、CriteriaAndroid开发笔记(四十六)手机相关事件
    通话管理TelephonyManagerAndroid开发笔记(四十六)手机相关事件
    基站信息CellLocation、CellInfoAndroid开发笔记(四十六)手机相关事件
    处理器Handler、Looper、MessageAndroid开发笔记(四十八)Thread类实现多线程
    异步任务AsyncTaskAndroid开发笔记(四十九)异步任务处理AsyncTask
    倒计时器CountDownTimerAndroid开发笔记(五十)定时器AlarmManager
    定时器管理AlarmManagerAndroid开发笔记(五十)定时器AlarmManager
    延迟的意图PendingIntentAndroid开发笔记(五十)定时器AlarmManager
    信使Messenger、IBinderAndroid开发笔记(五十一)通过Messenger实现进程间通信
    通知管理Notification、NotificationManagerAndroid开发笔记(五十二)通知推送Notification
    远程接口AIDLAndroid开发笔记(五十三)远程接口调用AIDL
    内容提供者ContentProviderAndroid开发笔记(五十四)数据共享接口ContentProvider
    内容解决者ContentResolverAndroid开发笔记(五十四)数据共享接口ContentProvider
    内容观察者ContentObserverAndroid开发笔记(五十四)数据共享接口ContentProvider
    版本信息BuildAndroid开发笔记(五十五)手机设备基本操作
    短信管理SmsManagerAndroid开发笔记(五十五)手机设备基本操作
    摄像头CameraAndroid开发笔记(五十六)摄像头拍照
    音频管理AudioManagerAndroid开发笔记(五十八)铃声与震动
    震动器VibratorAndroid开发笔记(五十八)铃声与震动
    传感器Sensor、SensorManagerAndroid开发笔记(五十九)巧用传感器
    连接管理ConnectivityManagerAndroid开发笔记(六十)网络的检测与连接
    热点管理WifiManagerAndroid开发笔记(六十)网络的检测与连接
    下载管理DownloadManagerAndroid开发笔记(六十一)文件下载与上传
    json数据JSONObject、JSONArrayAndroid开发笔记(六十二)HTTP数据格式的解析
    窗口WindowAndroid开发笔记(六十六)自定义对话框
    java原生接口JNIAndroid开发笔记(六十九)JNI实战
    日志LogAndroid开发笔记(七十一)区分开发模式和上线模式
    提示ToastAndroid开发笔记(七十一)区分开发模式和上线模式
    代码混淆ProguardAndroid开发笔记(七十三)代码混淆与反破解
    存储管理StorageManagerAndroid开发笔记(七十九)资源与权限校验
    流量统计TrafficStatsAndroid开发笔记(七十九)资源与权限校验
    打包管理PackageManager、PackageInfoAndroid开发笔记(八十)运行状态检查
    活动管理ActivityManagerAndroid开发笔记(八十)运行状态检查
    屏幕配置ConfigurationAndroid开发笔记(八十一)屏幕规格适配
    剪贴板管理ClipboardManagerAndroid开发笔记(一百零五)社会化分享SDK
    参数设置页面PreferenceActivityAndroid开发笔记(一百零八)语音识别与合成
    仪器测试用例InstrumentationTestCaseAndroid开发笔记(一百一十三)测试工具
    页面测试用例ActivityTestCaseAndroid开发笔记(一百一十三)测试工具
    电源管理PowerManagerAndroid开发笔记(一百一十七)app省电方略
    电池管理BatteryManagerAndroid开发笔记(一百一十七)app省电方略
    窗口管理WindowManagerAndroid开发笔记(一百一十八)自定义悬浮窗
    电话管理TelephonyManagerAndroid开发笔记(一百二十八)手机制式适配
    媒体投影管理MediaProjectionManagerAndroid开发笔记(一百三十)截图和录屏
    图像读取ImageReaderAndroid开发笔记(一百三十)截图和录屏
    媒体编码与转换MediaCodec、MediaMuxerAndroid开发笔记(一百三十)截图和录屏
    可缩放矢量图形SVGAndroid开发笔记(一百三十二)矢量图形与矢量动画
    PDF文件渲染PdfRendererAndroid开发笔记(一百四十二)平滑翻页的书籍浏览
    任务调度JobInfo、JobScheduler、JobServiceAndroid开发笔记(一百四十三)任务调度JobScheduler
    NFC适配器NfcAdapterAndroid开发笔记(一百六十一)NFC近场通信
    NFC传统类型MifareClassicAndroid开发笔记(一百六十一)NFC近场通信
    蓝牙适配器BluetoothAdapterAndroid开发笔记(一百六十二)蓝牙设备的连接与配对
    蓝牙设备BluetoothDeviceAndroid开发笔记(一百六十二)蓝牙设备的连接与配对
    红外遥控管理器ConsumerIrManagerAndroid开发笔记(一百六十五)利用红外发射遥控电器

     

     

     

    自定义控件

    红字标注的是来自于网络的开源代码

     

     

     

     

    名称类名出处
    简单的下拉刷新PullToRefreshLinearLayoutAndroid开发笔记(十二)测量尺寸与下拉刷新
    圆弧进度动画CircleAnimationAndroid开发笔记(十四)圆弧进度动画
    秋千摇摆动画SwingAnimationAndroid开发笔记(十六)秋千摇摆动画
    Gif动画GifAnimationAndroid开发笔记(十七)GIF动画的实现
    书籍翻页动画PageWidgetAndroid开发笔记(十八)书籍翻页动画
    底部标签页(三种)TabBarAndroid开发笔记(十九)底部标签栏TabBar
    横幅轮播页1BannerFlipperAndroid开发笔记(二十一)横幅轮播页Banner
    横幅轮播页2BannerPagerAndroid开发笔记(二十一)横幅轮播页Banner
    瀑布流网格WaterfallGridViewAndroid开发笔记(二十二)瀑布流网格WaterfallGridView
    日期对话框CalendarDialogAndroid开发笔记(二十三)文件对话框FileDialog
    信息确认对话框ConfirmDialogFragmentAndroid开发笔记(二十三)文件对话框FileDialog
    文件打开对话框FileSelectFragmentAndroid开发笔记(二十三)文件对话框FileDialog
    文件保存对话框FileSaveFragmentAndroid开发笔记(二十三)文件对话框FileDialog
    基于AutoCompleteTextView的搜索框AutoSearchViewAndroid开发笔记(四十四)动态UI事件
    基于EditText+ListView的搜索框CustomSearchViewAndroid开发笔记(四十四)动态UI事件
    不拦截水平滑动的滚动视图CustomScrollViewAndroid开发笔记(四十五)手势事件
    拍照视图CameraViewAndroid开发笔记(五十六)摄像头拍照
    二维码/条形码扫描MipcaActivityCaptureAndroid开发笔记(五十六)摄像头拍照
    带数字进度的进度条CustomProgressBarAndroid开发笔记(六十一)文件下载与上传
    滚轮对话框WheelDialogAndroid开发笔记(六十六)自定义对话框
    简单的图片缓存ImageCacheAndroid开发笔记(七十七)图片缓存算法
    程序崩溃信息采集CrashHandlerAndroid开发笔记(七十八)异常容错处理
    水波动画1RevealLayoutAndroid开发笔记(八十二)系统软件兼容
    水波动画2RippleViewAndroid开发笔记(八十二)系统软件兼容
    水波动画3MaterialRippleLayoutAndroid开发笔记(八十二)系统软件兼容
    圆形图像CircleDrawableAndroid开发笔记(九十五)自定义Drawable
    椭圆形图像OvalDrawableAndroid开发笔记(九十五)自定义Drawable
    圆角矩形图像RoundDrawableAndroid开发笔记(九十五)自定义Drawable
    水印图像MarkDrawableAndroid开发笔记(九十五)自定义Drawable
    灰度动画图像AlphaDrawableAndroid开发笔记(九十五)自定义Drawable
    手写签名SignatureViewAndroid开发笔记(九十八)往图片添加部件
    可旋转文本RotateTextViewAndroid开发笔记(九十九)圆形转盘
    可旋转图像RotateImageViewAndroid开发笔记(九十九)圆形转盘
    抽奖转盘LuckyPanViewAndroid开发笔记(九十九)圆形转盘
    圆形菜单CircleMenuLayoutAndroid开发笔记(九十九)圆形转盘
    更多动态视图MoreNewsViewAndroid开发笔记(一百)折叠式列表
    可折叠布局FoldingLayoutAndroid开发笔记(一百)折叠式列表
    水平列表视图HorizontalListViewAndroid开发笔记(一百零一)滑出式菜单
    视频播放器CustomVideoViewAndroid开发笔记(一百二十五)自定义视频播放器
    视频控制条VideoControllerAndroid开发笔记(一百二十五)自定义视频播放器
    音乐播放器MusicPlayerAndroid开发笔记(一百二十六)自定义音乐播放器
    音频控制条AudioControllerAndroid开发笔记(一百二十六)自定义音乐播放器
    水波动画RippleViewAndroid开发笔记(一百三十一)水波图形与水波动画
    协调的图像视图CoordinatorImageViewAndroid开发笔记(一百三十七)自定义行为Behavior
    图像视图行为ImageViewBehaviorAndroid开发笔记(一百三十七)自定义行为Behavior
    层叠翻页视图ViewSliderAndroid开发笔记(一百四十二)平滑翻页的书籍浏览
    书页视图BookViewAndroid开发笔记(一百四十二)平滑翻页的书籍浏览
    支付密码输入框PayPasswodInputAndroid开发笔记(一百四十六)仿支付宝的支付密码输入框
    纯数字软键盘KeyboardLayoutAndroid开发笔记(一百四十八)自定义输入法软键盘
    沉浸式状态栏StatusBarUtilAndroid开发笔记(一百六十三)高仿京东的沉浸式状态栏
    下拉滚动视图PullDownScrollViewAndroid开发笔记(一百六十四)仿京东首页的下拉刷新
    下拉刷新布局PullDownRefreshLayoutAndroid开发笔记(一百六十四)仿京东首页的下拉刷新

     

     

     

     

    第三方库

     

     

     

     

    名称包名出处
    下拉刷新com.handmark.pulltorefresh.libraryAndroid开发笔记(十二)测量尺寸与下拉刷新
    瀑布流网格SGVcom.etsy.android.gridAndroid开发笔记(二十二)瀑布流网格WaterfallGridView
    瀑布流网格PLAVcom.huewu.pla.libAndroid开发笔记(二十二)瀑布流网格WaterfallGridView
    excel文件解析jxlAndroid开发笔记(三十四)Excel文件的读写
    二维码/条形码扫描com.google.zxingAndroid开发笔记(五十六)摄像头拍照
    json解析com.alibaba.fastjsonAndroid开发笔记(六十二)HTTP数据格式的解析
    html解析org.jsoupAndroid开发笔记(六十二)HTTP数据格式的解析
    httpclient通信org.apache.http.entity.mimeAndroid开发笔记(六十三)HTTP访问的通信方式
    httpclient核心org.apache.httpAndroid开发笔记(六十三)HTTP访问的通信方式
    滚轮视图kankan.wheel.widgetAndroid开发笔记(六十六)自定义对话框
    数据加密org.bouncycastleAndroid开发笔记(七十二)数据加密算法
    数据加密org.apache.commons.codecAndroid开发笔记(七十二)数据加密算法
    图片缓存PCScom.squareup.picassoAndroid开发笔记(七十七)图片缓存算法
    okhttp网络通信2com.squareup.okhttpAndroid开发笔记(七十七)图片缓存算法
    okhttp流处理okioAndroid开发笔记(七十七)图片缓存算法
    图片缓存UILcom.nostra13.universalimageloaderAndroid开发笔记(七十七)图片缓存算法
    汉字转拼音net.sourceforge.pinyin4jAndroid开发笔记(八十三)多语言支持
    移动数据库io.realmAndroid开发笔记(八十五)手机数据库Realm
    REST网络通信框架retrofitAndroid开发笔记(八十五)手机数据库Realm
    滑出式菜单com.jeremyfeinstein.slidingmenu.libAndroid开发笔记(一百零一)滑出式菜单
    统计图表ACEorg.achartengineAndroid开发笔记(一百零二)统计图表
    统计图表MPcom.github.mikephil.chartingAndroid开发笔记(一百零二)统计图表
    动画兼容旧版本com.nineoldandroidsAndroid开发笔记(一百零二)统计图表
    统计图表XCLcom.demo.xclchartsAndroid开发笔记(一百零二)统计图表
    百度地图与定位com.baidu.mapapi
    com.baidu.location
    Android开发笔记(一百零三)地图与定位SDK
    高德地图与定位com.amap.apiAndroid开发笔记(一百零三)地图与定位SDK
    极光推送cn.jpushAndroid开发笔记(一百零四)消息推送SDK
    个推com.igexinAndroid开发笔记(一百零四)消息推送SDK
    友盟社会化分享com.umeng.socializeAndroid开发笔记(一百零五)社会化分享SDK
    QQ、QQ空间分享
    腾讯微博分享
    com.tencent.open
    com.tencent.connect
    Android开发笔记(一百零五)社会化分享SDK
    微信好友分享
    朋友圈分享
    com.tencent.mmAndroid开发笔记(一百零五)社会化分享SDK
    新浪微博com.sina.weibo.sdkAndroid开发笔记(一百零五)社会化分享SDK
    支付宝com.alipayAndroid开发笔记(一百零六)支付缴费SDK
    微信支付com.tencent.mm.sdkAndroid开发笔记(一百零六)支付缴费SDK
    银联支付com.unionpayAndroid开发笔记(一百零六)支付缴费SDK
    友盟统计分析com.umeng.analytics
    com.ta.utdid2
    Android开发笔记(一百零七)统计分析SDK
    百度统计分析com.baidu.mobstat
    com.baidu.bottom
    Android开发笔记(一百零七)统计分析SDK
    腾讯统计分析com.tencent.mid
    com.tencent.stat
    Android开发笔记(一百零七)统计分析SDK
    科大讯飞语音com.iflytekAndroid开发笔记(一百零八)语音识别与合成
    百度语音识别com.baidu.speechAndroid开发笔记(一百零八)语音识别与合成
    百度语音合成com.baidu.ttsAndroid开发笔记(一百零八)语音识别与合成
    百度网盘com.baidu.oauth
    com.baidu.pcs
    Android开发笔记(一百零九)利用网盘实现云存储
    阿里云com.alibaba.sdk.android.ossAndroid开发笔记(一百零九)利用网盘实现云存储
    异步HTTP库com.loopj.android.httpAndroid开发笔记(一百一十)使用http框架上传文件
    Retrofitretrofit2Android开发笔记(一百一十)使用http框架上传文件
    okhttp网络通信3okhttp3Android开发笔记(一百一十)使用http框架上传文件
    okhttp流处理okioAndroid开发笔记(一百一十)使用http框架上传文件
    常用网络命令库
    (ftp/telnet/smtp)
    org.apache.commons.netAndroid开发笔记(一百一十)使用http框架上传文件
    sftp库com.jcraft.jschAndroid开发笔记(一百一十)使用http框架上传文件
    自动化测试com.robotium.soloAndroid开发笔记(一百一十三)测试工具
    word文本解析org.textmining.textAndroid开发笔记(一百四十)Word文件的读取与显示
    office解析poi库org.apache.poi.hwpfAndroid开发笔记(一百四十)Word文件的读取与显示
    office解析poi库org.apache.poi.hslfAndroid开发笔记(一百四十一)读取PPT和PDF文件
    pdf解析Vudroid库org.vudroid.pdfdroidAndroid开发笔记(一百四十一)读取PPT和PDF文件
    pdf解析MuPDF库com.artifex.mupdfAndroid开发笔记(一百四十一)读取PPT和PDF文件
    卷曲视图fi.harism.curlAndroid开发笔记(一百五十七)使用OpenGL实现翻书动画

     

     

     


    本系列的开发笔记已有部分文章整理成书出版,有兴趣的读者可移步前往《Android Studio开发实战 从零基础到App上线》
    __________________________________________________________________________
    博主现已开通微信公众号“老欧说安卓”,打开微信扫一扫下面的二维码,或者直接搜索公众号“老欧说安卓”添加关注,更快更方便地阅读技术干货。

     

     

     

     

     

     

     

    展开全文
  • 文字识别(六)--不定长文字识别CRNN算法详解

    万次阅读 多人点赞 2019-02-18 15:34:54
    我们一般都会讲一连串文字的文本文件先利用投影法切割出单个字体,送入CNN里进行文字分类。但是此法已经有点过时了,现在更流行的是基于深度学习的端到端的文字识别,即我们不需要显式加入文字切割这个环节,而是...

    转自:https://www.cnblogs.com/skyfsm/p/10335717.html

    在以前的OCR任务中,识别过程分为两步:单字切割和分类任务。我们一般都会讲一连串文字的文本文件先利用投影法切割出单个字体,在送入CNN里进行文字分类。但是此法已经有点过时了,现在更流行的是基于深度学习的端到端的文字识别,即我们不需要显式加入文字切割这个环节,而是将文字识别转化为序列学习问题,虽然输入的图像尺度不同,文本长度不同,但是经过DCNN和RNN后,在输出阶段经过一定的翻译后,就可以对整个文本图像进行识别,也就是说,文字的切割也被融入到深度学习中去了。

    现今基于深度学习的端到端OCR技术有两大主流技术:CRNN OCR和attention OCR。其实这两大方法主要区别在于最后的输出层(翻译层),即怎么将网络学习到的序列特征信息转化为最终的识别结果。这两大主流技术在其特征学习阶段都采用了CNN+RNN的网络结构,CRNN OCR在对齐时采取的方式是CTC算法,而attention OCR采取的方式则是attention机制。本文将介绍应用更为广泛的CRNN算法。

    网络结构包含三部分,从下到上依次为:

    1. 卷积层,使用CNN,作用是从输入图像中提取特征序列;
    2. 循环层,使用RNN,作用是预测从卷积层获取的特征序列的标签(真实值)分布;
    3. 转录层,使用CTC,作用是把从循环层获取的标签分布通过去重整合等操作转换成最终的识别结果;

    端到端OCR的难点在哪儿呢?在于怎么处理不定长序列对齐问题!CRNN OCR其实是借用了语音识别中解决不定长语音序列的思路。与语音识别问题类似,OCR可建模为时序依赖的词汇或者短语识别问题。基于联结时序分类(Connectionist Temporal Classification, CTC)训练RNN的算法,在语音识别领域显著超过传统语音识别算法。一些学者尝试把CTC损失函数借鉴到OCR识别中,CRNN 就是其中代表性算法。CRNN算法输入100*32归一化高度的词条图像,基于7层CNN(普遍使用VGG16)提取特征图,把特征图按列切分(Map-to-Sequence),每一列的512维特征,输入到两层各256单元的双向LSTM进行分类。在训练过程中,通过CTC损失函数的指导,实现字符位置与类标的近似软对齐。

    CRNN借鉴了语音识别中的LSTM+CTC的建模方法,不同点是输入进LSTM的特征,从语音领域的声学特征(MFCC等),替换为CNN网络提取的图像特征向量。CRNN算法最大的贡献,是把CNN做图像特征工程的潜力与LSTM做序列化识别的潜力,进行结合。它既提取了鲁棒特征,又通过序列识别避免了传统算法中难度极高的单字符切分与单字符识别,同时序列化识别也嵌入时序依赖(隐含利用语料)。在训练阶段,CRNN将训练图像统一缩放100×32(w × h);在测试阶段,针对字符拉伸导致识别率降低的问题,CRNN保持输入图像尺寸比例,但是图像高度还是必须统一为32个像素,卷积特征图的尺寸动态决定LSTM时序长度。这里举个例子

    现在输入有个图像,为了将特征输入到Recurrent Layers,做如下处理:

    • 首先会将图像缩放到 32×W×1 大小
    • 然后经过CNN后变为 1×(W/4)× 512
    • 接着针对LSTM,设置 T=(W/4) , D=512 ,即可将特征输入LSTM。
    • LSTM有256个隐藏节点,经过LSTM后变为长度为T × nclass的向量,再经过softmax处理,列向量每个元素代表对应的字符预测概率,最后再将这个T的预测结果去冗余合并成一个完整识别结果即可。

    CRNN中需要解决的问题是图像文本长度是不定长的,所以会存在一个对齐解码的问题,所以RNN需要一个额外的搭档来解决这个问题,这个搭档就是著名的CTC解码。
    CRNN采取的架构是CNN+RNN+CTC,cnn提取图像像素特征,rnn提取图像时序特征,而ctc归纳字符间的连接特性。

    那么CTC有什么好处?因手写字符的随机性,人工可以标注字符出现的像素范围,但是太过麻烦,ctc可以告诉我们哪些像素范围对应的字符:

    我们知道,CRNN中RNN层输出的一个不定长的序列,比如原始图像宽度为W,可能其经过CNN和RNN后输出的序列个数为S,此时我们要将该序列翻译成最终的识别结果。RNN进行时序分类时,不可避免地会出现很多冗余信息,比如一个字母被连续识别两次,这就需要一套去冗余机制,但是简单地看到两个连续字母就去冗余的方法也有问题,比如cook,geek一类的词,所以CTC有一个blank机制来解决这个问题。这里举个例子来说明。

    如上图所示,我们要识别这个手写体图像,标签为“ab”,经过CNN+RNN学习后输出序列向量长度为5,即t0~t4,此时我们要将该序列翻译为最后的识别结果。我们在翻译时遇到的第一个难题就是,5个序列怎么转化为对应的两个字母?重复的序列怎么解决?刚好位于字与字之间的空白的序列怎么映射?这些都是CTC需要解决的问题。

    我们从肉眼可以看到,t0,t1,t2时刻都应映射为“a”,t3,t4时刻都应映射为“b”。如果我们将连续重复的字符合并成一个输出的话,即“aaabb”将被合并成“ab”输出。但是这样子的合并机制是有问题的,比如我们的标签图像时“aab”时,我们的序列输出将可能会是“aaaaaaabb”,这样子我们就没办法确定该文本应被识别为“aab”还是“ab”。CTC为了解决这种二义性,提出了插入blank机制,比如我们以“-”符号代表blank,则若标签为“aaa-aaaabb”则将被映射为“aab”,而“aaaaaaabb”将被映射为“ab”。引入blank机制,我们就可以很好地处理了重复字符的问题了。

    但我们还注意到,“aaa-aaaabb”可以映射为“aab”,同样地,“aa-aaaaabb”也可以映射为“aab”,也就是说,存在多个不同的字符组合可以映射为“aab”,更总结地说,一个标签存在一条或多条的路径。比如下面“state”这个例子,也存在多条不同路径映射为"state":

    上面提到,RNN层输出的是序列中概率矩阵,那么

    ,其中,y1−表示第一个序列输出“-”的概率,那么对于输出某条路径ππ的概率为各个序列概率的乘积。所以要得到一个标签可以有多个路径来获得,从直观上理解就是,我们输出一张文本图像到网络中,我们需要使得输出为标签L的概率最大化,由于路径之间是互斥的,对于标注序列,其条件概率为所有映射到它的路径概率之和:

    其中π∈B−1(l)的意思是,所有可以合并成l的所有路径集合。

    这种通过映射B和所有候选路径概率之和的方式使得CTC不需要对原始的输入序列进行准确的切分,这使得RNN层输出的序列长度>label长度的任务翻译变得可能。CTC可以与任意的RNN模型,但是考虑到标注概率与整个输入串有关,而不是仅与前面小窗口范围的片段相关,因此双向的RNN/LSTM模型更为适合。

    ctc会计算loss ,从而找到最可能的像素区域对应的字符。事实上,这里loss的计算本质是对概率的归纳:

    如上图,对于最简单的时序为2的(t0t1)的字符识别,可能的字符为“a”,“b”和“-”,颜色越深代表概率越高。我们如果采取最大概率路径解码的方法,一看就是“--”的概率最大,真实字符为空即“”的概率为0.6*0.6=0.36。

    但是我们忽略了一点,真实字符为“a”的概率不只是”aa” 即0.4*0.4 , 事实上,“aa”, “a-“和“-a”都是代表“a”,所以,输出“a”的概率为:

    0.4*0.4 + 0.4 * 0.6 + 0.6*0.4 = 0.16+0.24+0.24 = 0.64

    所以“a”的概率比空“”的概率高!可以看出,这个例子里最大概率路径和最大概率序列完全不同,所以CTC解码通常不适合采用最大概率路径的方法,而应该采用前缀搜索算法解码或者约束解码算法。

    通过对概率的计算,就可以对之前的神经网络进行反向传播更新。类似普通的分类,CTC的损失函数O定义为负的最大似然,为了计算方便,对似然取对数。

    我们的训练目标就是使得损失函数O优化得最小即可。

    展开全文
  • 1.原文地址:http://tomcat.apache.org/tomcat-8.5-doc/jdbc-pool.html 2.译者:chenjazz佳志 3.参考文档:...4.【】中的文字原文中不存在,属于解释性的===================以下为正文===

    说明:
    1. 英文文档原文地址:http://tomcat.apache.org/tomcat-8.5-doc/jdbc-pool.html
    2. 译者:陈佳志chenjazz
    3. 参考了另一篇翻译文档:http://wiki.jikexueyuan.com/project/tomcat/tomcat-jdbc-pool.html
    4. 【】中的文字原文中不存在,属于译者解释性的

    ===================以下为正文===================

    一、简介

    JDBC 连接池 org.apache.tomcat.jdbc.pool 是 Apache Commons DBCP 连接池的一种替换或备选方案。
    那为什么需要一个新的连接池?

    原因如下:
    1. Commons DBCP 1.x 是单线程。为了线程安全,在对象分配或对象返回的短期时间内,DBCP 锁定了整个连接池。但注意这并不适用于 Commons DBCP 2.x。【对象指的是Connection对象】
    2. Commons DBCP 1.x 可能会变得很慢。当逻辑 CPU 数目增长,或者试图借出或归还对象的并发线程增加时,性能就会受到影响。高并发系统受到的影响会更为显著。注意这并不适用于 Commons DBCP 2.x。
    3. Commons DBCP 拥有 60 多个类。tomcat-jdbc-pool 核心只有 8 个类。因此如果未来需求变更着想,仅需要更少的改动。我们真正需要的只是连接池本身,其余的只是附属。
    4. Commons DBCP 使用静态接口,因此对于指定版本的 JRE,只能采用正确版本的 DBCP,否则就会出现 NoSuchMethodException 异常。
    5. 当DBCP 可以用其他更简便的实现来替代时,实在不值得重写那 60 个类。
    6. Tomcat JDBC 连接池无需为库本身添加额外线程,就能获取异步获取连接。
    7. Tomcat JDBC 连接池是 Tomcat 的一个模块,仅依赖Tomcat JULI 这个Tomcat中的简化日志架构。
    8. 可以使用 javax.sql.PooledConnection 接口获取底层连接。
    9. 防止饥饿。如果池变空,线程将等待一个连接。当连接返回时,池就将唤醒正确的等待线程。大多数连接池只会一直维持饥饿状态。【?】

    Tomcat JDBC 连接池还具有一些其他连接池实现所没有的特点:

    1. 支持高并发环境与多核/CPU 系统。
    2. 接口的动态实现。在你的运行环境下支持 java.sql 与 java.sql 接口(就像 JDBC 驱动一样),甚至在利用低版本的 JDK 来编译时。
    3. 验证间隔时间。我们不必每次使用单个连接时都进行验证,可以在借出(borrow )或归还(return )连接时进行验证,只要不低于我们所设定的间隔时间就行。
    4. 只执行一次查询。当与数据库建立起连接时,只执行一次的可配置查询。这项功能对会话设置非常有用,因为你可能会想在连接建立的整个时段内都保持会话。
    5. 能够配置自定义拦截器。通过自定义拦截器来增强功能。可以使用拦截器来采集查询统计,缓存会话状态,重新连接之前失败的连接,重新查询,缓存查询结果,等等。可以使用大量的选项并且自定义拦截器也是没有限制的没有绑定到特定版本JDK的 java.sql/javax.sql 接口。
    6. 高性能。后文将举例展示一些性能差异。
    7. 极其简单。它的实现非常简单,代码行数与源文件都非常少,这都有赖于从一开始研发它时,就把简洁当做重中之重。对比一下 c3p0 ,它的源文件超过了 200 个(最近一次统计),而 Tomcat JDBC 核心只有 8 个文件,连接池本身则大约只有这个数目的一半,所以能够轻易地跟踪和修改可能出现的 Bug。
    8. 异步连接获取。可将连接请求队列化,系统返回 Future<Connection>
    9. 更好地处理空闲连接。不再直接把空闲连接关闭,通过更为巧妙的算法控制空闲连接池的规模。
    10. 可以控制连接应被废弃的时间:当池满了即废弃,或者指定一个池使用容差值,发生超时就进行废弃处理。
    11. 通过查询或语句来重置废弃连接计时器。允许一个使用了很长时间的连接不因为超时而被废弃。这一点是通过使用 ResetAbandonedTimer 来实现的。
    12. 经过指定时间后,关闭连接。与返回池的时间相类似。
    13. 当连接要被释放时,获取 JMX 通知并记录所有日志。它类似于 removeAbandonedTimeout,但却不需要采取任何行为,只报告信息。通过 suspectTimeout 属性来实现。
    14. 可以通过 java.sql.Driver、javax.sql.DataSource 或 javax.sql.XADataSource 获取连接。通过 dataSource 与 dataSourceJNDI 属性实现这一点。
    15. 支持 XA 连接。
    16. 16.

    二、如何使用

    对于熟悉 Commons DBCP 的人来说,转而使用 Tomcat 连接池是非常简单的事。从其他连接池转换过来也非常容易。

    附加功能

    除了其他多数连接池能够提供的功能外,Tomcat 连接池还提供了一些附加功能:
    - initSQL 当连接创建后,能够执行一个只执行一次的SQL 语句。
    - validationInterval 恰当地在连接上运行验证,同时又能避免太多频繁地执行验证。
    - jdbcInterceptors 灵活并且可插拔的拦截器,能够对池进行各种自定义,执行各种查询,处理结果集。下文将予以详述。
    - fairQueue 将 fair 标志设为 true,以达成线程公平性,或使用异步连接获取。

    在Apache Tomcat 容器内部(使用)

    Tomcat JDBC 文档描述中:(在Tomcat 容器内部,)Tomcat 连接池被配置为一个资源。唯一的区别在于,你必须指定 factory 属性,并将其值设为

    org.apache.tomcat.jdbc.pool.DataSourceFactory

    独立(使用)

    连接池只有一个依赖文件,tomcat-juli.jar。要想在使用 bean 实例化的单一项目中使用池,实例化的 Bean 为org.apache.tomcat.jdbc.pool.DataSource。下文讲到将连接池配置为 JNDI 资源时会涉及到同一属性,也是用来将数据源配置成 bean 的。

    JMX

    连接池对象暴露了一个可以被注册的 MBean。为了让连接池对象创建 MBean,jmxEnabled 标志必须设为 true。这并不是说连接池会注册到 MBean 服务器。在像 Tomcat 这样的容器中,Tomcat 本身注册就在 MBean 服务器上注册了 DataSource。org.apache.tomcat.jdbc.pool.DataSource 对象会注册实际的连接池 MBean。如果你在容器外运行,可以将 DataSource 注册在任何你指定的对象名下,然后将这种注册传播到底层池。要想这样做,你必须调用 mBeanServer.registerMBean(dataSource.getPool().getJmxPool(),objectname)。在调用之前,一定要保证通过调用 dataSource.createPool() 创建了池。

    三、属性

    为了能够顺畅地在 Commons DBCP 与 Tomcat JDBC 连接池 之间转换,大多数属性名称及其含义都是相同的。

    JNDI 工厂与类型

    属性描述
    factory(必要属性),其值应为 org.apache.tomcat.jdbc.pool.DataSourceFactory
    type类型应为 javax.sql.DataSource 或 javax.sql.XADataSource。将创建对应的org.apache.tomcat.jdbc.pool.DataSource和org.apache.tomcat.jdbc.pool.XADataSource。

    系统属性

    系统属性作用于 JVM 范围,影响创建于 JVM 内的所有池。

    属性描述
    org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader布尔值,默认为 false。控制动态类(如JDBC 驱动、拦截器、验证器)的加载。如果采用默认值,池会首先利用当前类加载器(比如已经加载池类的类加载器)加载类;如果类加载失败,则尝试利用线程上下文加载器加载。取值为 true 时,会向后兼容 Apache Tomcat 8.0.8 及更早版本,只会采用当前类加载器。如果未设置,则取默认值。

    常用属性

    属性描述
    defaultAutoCommit(布尔值)连接池所创建的连接默认自动提交状态。如果未设置,则默认采用 JDBC 驱动的缺省值(如果未设置,则不会调用 setAutoCommit 方法)。
    defaultReadOnly(布尔值)连接池所创建的连接默认只读状态。如果未设置,将不会调用 setReadOnly 方法。(有些驱动并不支持只读模式,比如:informix),
    defaultTransactionIsolation(字符串)连接池所创建的连接的默认事务隔离状态。取值范围为:(参考 javadoc)NONEREAD_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ、SERIALIZABLE如果未设置该值,则不会调用任何方法,默认为 JDBC 驱动。
    defaultCatalog(字符串)连接池所创建的连接的默认catalog。
    driverClassName(字符串)所要使用的 JDBC 驱动的完全限定的 Java 类名。该驱动必须能从与 tomcat-jdbc.jar 同样的类加载器访问
    username(字符串)传入 JDBC 驱动以便建立连接的连接用户名。注意,DataSource.getConnection(username,password) 方法默认不会使用传入该方法内的凭证,但会使用这里的配置信息。可参看 alternateUsernameAllowed 了解更多详情。
    password(字符串)传入 JDBC 驱动以便建立连接的连接密码。注意,DataSource.getConnection(username,password) 方法默认不会使用传入该方法内的凭证,但会使用这里的配置信息。可参看 alternateUsernameAllowed 了解更多详情。
    maxActive(整形值)池同时能分配的活跃连接的最大数目。默认为 100。
    maxIdle(整型值)池始终都应保留的连接的最大数目。默认为 maxActive:100。会周期性检查空闲连接(如果启用该功能),留滞时间超过 minEvictableIdleTimeMillis 的空闲连接将会被释放。(请参考 testWhileIdle)【译者:maxIdle是一个很模糊的概念,druid连接池中已将此属性去除】
    minIdle(整型值)池始终都应保留的连接的最小数目。如果验证查询失败,则连接池会缩减该值。默认值取自 initialSize:10(请参考 testWhileIdle)。
    initialSize(整型值)连接器启动时创建的初始连接数。默认为 10。
    maxWait(整型值)在抛出异常之前,连接池等待(没有可用连接时)返回连接的最长时间,以毫秒计。默认为 30000(30 秒)
    testOnBorrow(布尔值)默认值为 false。从池中借出对象之前,是否对其进行验证。如果对象验证失败,将其从池中清除,再接着去借下一个。注意:为了让 true 值生效,validationQuery 参数必须为非空字符串。为了实现更高效的验证,可以采用 validationInterval。
    testOnReturn(布尔值)默认值为 false。将对象返回池之前,是否对齐进行验证。注意:为了让 true 值生效,validationQuery 参数必须为非空字符串。
    testWhileIdle(布尔值)是否通过空闲对象清除者(如果存在的话)验证对象。如果对象验证失败,则将其从池中清除。注意:为了让 true 值生效,validationQuery 参数必须为非空字符串。该属性默认值为 false,为了运行池的清除/测试线程,必须设置该值。(另请参阅 timeBetweenEvictionRunsMillis)
    validationQuery(字符串)在将池中连接返回给调用者之前,用于验证这些连接的 SQL 查询。如果指定该值,则该查询不必返回任何数据,只是不抛出 SQLException 异常。默认为 null。实例值为:SELECT 1(MySQL) select 1 from dual(Oracle) SELECT 1(MySQL Server)。
    validationQueryTimeout(整型值)连接验证失败前的超时时间(以秒计)。通过在执行
    validatorClassName(字符串)实现 org.apache.tomcat.jdbc.pool.Validator 接口并提供了一个无参(可能是隐式的)构造函数的类名。如果指定该值,将通过该类来创建一个 Validator 实例来验证连接,代替任何验证查询。默认为 null,范例值为:com.mycompany.project.SimpleValidator。
    timeBetweenEvictionRunsMillis(整型值)空闲连接验证/清除线程运行之间的休眠时间(以毫秒计)。不能低于 1 秒。该值决定了我们检查空闲连接、废弃连接的频率,以及验证空闲连接的频率。默认为 5000(5 秒)
    numTestsPerEvictionRun(整型值)Tomcat JDBC 连接池没有用到这个属性。
    minEvictableIdleTimeMillis(整型值)在被确定应被清除之前,对象在池中保持空闲状态的最短时间(以毫秒计)。默认为 60000(60 秒)
    accessToUnderlyingConnectionAllowed(布尔值)没有用到的属性。可以在归入池内的连接上调用 unwrap来访问。参阅 javax.sql.DataSource 接口的相关介绍,或者通过反射调用 getConnection,或者将对象映射为 javax.sql.PooledConnection。
    removeAbandoned(布尔值)该值为标志(Flag)值,表示如果连接时间超出了 removeAbandonedTimeout,则将清除废弃连接。如果该值被设置为 true,则如果连接时间大于 removeAbandonedTimeout,该连接会被认为是废弃连接,应予以清除。若应用关闭连接失败时,将该值设为 true 能够恢复该应用的数据库连接。另请参阅 logAbandoned。默认值为 false。
    removeAbandonedTimeout(整型值)在废弃连接(仍在使用)可以被清除之前的超时秒数。默认为 60(60 秒)。应把该值设定为应用可能具有的运行时间最长的查询。
    logAbandoned(布尔值)标志能够针对丢弃连接的应用代码,进行堆栈跟踪记录。由于生成堆栈跟踪,对废弃连接的日志记录会增加每一个借取连接的开销。默认为 false
    connectionProperties(字符串)在建立新连接时,发送给 JDBC 驱动的连接属性。字符串格式必须为:[propertyName=property;]*。注意:user 与 password 属性会显式传入,因此这里并不需要包括它们。默认为 null。
    poolPreparedStatements(布尔值)未使用的属性
    maxOpenPreparedStatements(整型值)未使用的属性

    增强属性

    属性描述
    initSQL(字符串值)当连接第一次创建时,运行的自定义查询。默认值为 null。
    jdbcInterceptors(字符串)继承自类 org.apache.tomcat.jdbc.pool.JdbcInterceptor 的子类类名列表,由分号分隔。关于格式及范例,可参见下文的配置 JDBC 拦截器。 这些拦截器将会插入到 java.sql.Connection 对象的操作队列中。 预定义的拦截器有: org.apache.tomcat.jdbc.pool.interceptor ConnectionState——记录自动提交、只读、catalog以及事务隔离级别等状态。 org.apache.tomcat.jdbc.pool.interceptor StatementFinalizer——记录打开的语句,并当连接返回池后关闭它们。 有关更多预定义拦截器的详尽描述,可参阅JDBC 拦截器
    validationInterval(长整型值)为避免过度验证而设定的频率时间值(以秒计)。最多以这种频率运行验证。如果连接应该进行验证,但却没能在此间隔时间内得到验证,则会重新对其进行验证。默认为 30000(30 秒)。
    jmxEnabled(布尔值)是否利用 JMX 注册连接池。默认为 true。
    fairQueue(布尔值)假如想用真正的 FIFO 方式公平对待 getConnection 调用,则取值为 true。对空闲连接列表将采用 org.apache.tomcat.jdbc.pool.FairBlockingQueue 实现。默认值为 true。如果想使用异步连接获取功能,则必须使用该标志。 设置该标志可保证线程能够按照连接抵达顺序来接收连接。 在性能测试时,锁及锁等待的实现方式有很大差异。当 fairQueue=true 时,根据所运行的操作系统,存在一个决策过程。假如系统运行在 Linux 操作系统(属性 os.name = linux)上,为了禁止这个 Linux 专有行为,但仍想使用公平队列,那么只需在连接池类加载之前,将 org.apache.tomcat.jdbc.pool.FairBlockingQueue.ignoreOS=true 添加到系统属性上。
    abandonWhenPercentageFull(整型值)除非使用中连接的数目超过 abandonWhenPercentageFull 中定义的百分比,否则不会关闭并报告已废弃的连接(因为超时)。取值范围为 0-100。默认值为 0,意味着只要达到 removeAbandonedTimeout,就应关闭连接。
    maxAge(长整型值)连接保持时间(以毫秒计)。当连接要返回池中时,连接池会检查是否达到 now - time-when-connected > maxAge 的条件,如果条件达成,则关闭该连接,不再将其返回池中。默认值为 0,意味着连接将保持开放状态,在将连接返回池中时,不会执行任何年龄检查。
    useEquals(布尔值)。如果想让 ProxyConnection 类使用 String.equals,则将该值设为 true;若想在对比方法名称时使用 ==,则应将其设为 false。该属性不能用于任何已添加的拦截器中,因为那些拦截器都是分别配置的。默认值为 true。
    suspectTimeout(整型值)超时时间(以秒计)。默认值为 0。类似于 removeAbandonedTimeout,但不会把连接当做废弃连接从而有可能关闭连接。如果 logAbandoned 设为 true,它只会记录下警告。如果该值小于或等于 0,则不会执行任何怀疑式检查。如果超时值大于 0,而连接还没有被废弃,或者废弃检查被禁用时,才会执行怀疑式检查。如果某个连接被怀疑到,则记录下 WARN 信息并发送一个 JMX 通知。
    rollbackOnReturn(布尔值)如果 autoCommit==false,那么当连接返回池中时,池会在连接上调用回滚方法,从而终止事务。默认值为 false。
    commitOnReturn布尔值。如果 autoCommit==false,那么当连接返回池中时,池会在连接上调用提交方法,从而完成事务;如果 rollbackOnReturn==true,则忽略该属性。默认值为 false。
    alternateUsernameAllowed(布尔值)出于性能考虑,JDBC 连接池默认会忽略 DataSource.getConnection(username,password)调用,只返回之前池化的具有全局配置属性 username 和 password的连接。 但经过配置,连接池还可以允许使用不同的凭证来请求每一个连接。为了启用这项在 DataSource.getConnection(username,password)调用中描述的功能,只需将 alternateUsernameAllowed 设为 true。 如果你请求一个连接,凭证为 user 1/password 1,而连接之前使用的是 user 2/password 2 凭证,那么连接将被关闭,重新利用请求的凭证来开启。按照这种方式,池的容量始终以全局级别管理,而不是限于模式(schema)级别。 默认值为 false。 该属性作为一个改进方案,被添加到了 bug 50025 中。
    dataSource(javax.sql.DataSource)将数据源注入连接池,从而使池利用数据源来获取连接,而不是利用 java.sql.Driver 接口来建立连接。它非常适于使用数据源(而非连接字符串)来池化 XA 连接或者已建立的连接时。默认值为 null。
    dataSourceJNDI(字符串)在 JNDI 中查找的数据源的 JNDI 名称,随后将用于建立数据库连接。参看 datasource 属性的介绍。默认值为 null。
    useDisposableConnectionFacade(布尔值)如果希望在连接上放上一个门面对象,从而使连接在关闭后无法重用,则要将值设为 true。这能防止线程继续引用一个已被关闭的连接,并继续在连接上查询。默认值为 true。
    logValidationErrors(布尔值)。设为 true 时,能将验证阶段的错误记录到日志文件中,错误会被记录为 SEVERE。考虑到了向后兼容性,默认值为 false。
    propagateInterruptState(布尔值)。传播已中断的线程(还没有清除中断状态)的中断状态。考虑到了向后兼容性,默认值为 false。
    ignoreExceptionOnPreLoad(布尔值)。在初始化池时,是否忽略连接创建错误。取值为 true时表示忽略;设为 false 时,抛出异常,从而宣告池初始化失败。默认值为 false。

    四、高级用法

    JDBC 拦截器

    要想看看拦截器使用方法的具体实例,可以看看 org.apache.tomcat.jdbc.pool.interceptor.ConnectionState源码。这个简单的拦截器缓存了三个属性:autoCommit、readOnly、transactionIsolation,为的是避免系统与数据库之间无用的往返。

    当需求增加时,连接池核心将会增加更多的拦截器。欢迎贡献你的才智!

    拦截器当然并不局限于 java.sql.Connection,当然也可以对方法调用的任何结果进行包装。你可以构建查询性能分析器,以便当查询运行时间超过预期时间时提供 JMX 通知。

    配置 JDBC 拦截器

    JDBC 拦截器是通过 jdbcInterceptor 属性来配置的。该属性值包含一列由分号分隔的类名。如果这些类名非完全限定,就会在它们的前面加上 org.apache.tomcat.jdbc.pool.interceptor. 前缀。
    范例:

    jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"

    等同于:

    jdbcInterceptors="ConnectionState;StatementFinalizer"

    拦截器也同样有属性。拦截器的属性指定在类名后的括号里,如果设置多个属性,则用逗号分隔开。

    范例:

    jdbcInterceptors="ConnectionState;StatementFinalizer(useEquals=true)"
    

    系统会自动忽略属性名称、属性值以及类名前后多余的空格字符。

    org.apache.tomcat.jdbc.pool.JdbcInterceptor

    这个类用来是所有拦截器的抽象基类,它无法被实例化。

    属性描述
    useEquals(布尔值)如果希望 ProxyConnection 类使用 String.equals,则设为 true;当希望在对比方法名时使用 ==,则设为 false。默认为 true。

    org.apache.tomcat.jdbc.pool.interceptor.ConnectionState

    这个类能为下列属性缓存连接:autoCommit、readOnly、transactionIsolation 及 catalog。这是一种性能增强功能,当利用已设定的值来调用 getter 与 setter 时,它能够避免往返数据库。

    org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer

    这个类用来跟踪所有使用 createStatement、prepareStatement 或 prepareCall 的语句,当连接返回池后,关闭这些语句。

    属性描述
    trace(以字符串形式表示的布尔值)对未关闭语句进行跟踪。当启用跟踪且连接被关闭时,如果相关语句没有关闭,则拦截器会记录所有的堆栈跟踪。默认值为 false。

    org.apache.tomcat.jdbc.pool.interceptor.StatementCache

    缓存连接中的 PreparedStatement 或 CallableStatement 实例。

    它会针对每个连接对这些语句进行缓存,然后计算池中所有连接的整体缓存数,如果缓存数超过了限制 max,就不再对随后的语句进行缓存,而是直接关闭它们。

    属性描述
    prepared(以字符串形式表示的布尔值)对使用 prepareStatement 调用创建的 PreparedStatement 实例进行缓存。默认为 true
    callable(以字符串形式表示的布尔值)对使用 prepareCall 调用创建的 CallableStatement 实例进行缓存。默认为 false
    max(以字符串形式表示的整型值)连接池中的缓存语句的数量限制。默认为 50

    org.apache.tomcat.jdbc.pool.interceptor.StatementDecoratorInterceptor

    请参看 48392【bug : https://bz.apache.org/bugzilla/show_bug.cgi?id=48392】。拦截器会包装语句和结果集,从而防止对使用了 ResultSet.getStatement().getConnection() 和 Statement.getConnection() 方法的实际连接进行访问。

    org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor

    当新语句创建时,自动调用 java.sql.Statement.setQueryTimeout(seconds)。池本身并不会让查询超时,完全是依靠 JDBC 驱动来强制查询超时。

    属性描述
    queryTimeout(以字符串形式表示的整型值)查询超时的毫秒数。默认为 1000 毫秒。

    org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport

    当查询超过失败容差值时,记录查询性能并发布日志项目。使用的日志级别为 WARN。

    属性描述
    threshold(以字符串形式表示的整型值)查询应超时多少毫秒才发布日志警告。默认为 1000 毫秒
    maxQueries(以字符串形式表示的整型值)为保留内存空间,所能记录的最大查询数量。默认为 1000
    logSlow(以字符串形式表示的布尔值)如果想记录较慢的查询,设为 true。默认为 true
    logFailed(以字符串形式表示的布尔值)如果想记录失败查询,设为 true。默认为 true

    org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx

    这是对 SlowQueryReport 的扩展,除了发布日志项目外,它还发布 JMX 通知,以便监视工具作出相关反应。该类从其父类继承了所有属性。它使用了 Tomcat 的 JMX 引擎,所以在 Tomcat 容器外部是无效的。使用该类时,默认情况下,是通过 ConnectionPool MBean 来发送 JMX 通知。如果 notifyPool=false,则 SlowQueryReportJmx 也可以注册一个 MBean。

    属性描述
    notifyPool(以字符串形式表示的布尔值)如果希望用 SlowQueryReportJmx MBean 发送 JMX 通知,则设为 false。默认为 true
    objectName字符串。定义一个有效的 javax.management.ObjectName 字符串,用于将这一对象注册到平台所用的 mbean 服务器上。默认值为 null。可以使用 tomcat.jdbc:type=org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx,name=the-name-of-the-pool 来注册对象。

    org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer

    当连接签出池中后,废弃计时器即开始计时。这意味着如果超时为 30 秒,而你使用连接运行了 10 个 10秒的查询,那么它就会被标为废弃,并可能依靠 abandonWhenPercentageFull 属性重新声明。每次成功地在连接上执行操作或执行查询时,该拦截器就会重设签出计时器。

    五、代码示例

    其他 JDBC 用途的 Tomcat 配置范例可以参考 相关的 Tomcat 文档。

    简单的 Java程序

    下面这个简单的范例展示了如何创建并使用数据源:

    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    import org.apache.tomcat.jdbc.pool.DataSource;
    import org.apache.tomcat.jdbc.pool.PoolProperties;
    
    public class SimplePOJOExample {
    
          public static void main(String[] args) throws Exception {
              PoolProperties p = new PoolProperties();
              p.setUrl("jdbc:mysql://localhost:3306/mysql");
              p.setDriverClassName("com.mysql.jdbc.Driver");
              p.setUsername("root");
              p.setPassword("password");
              p.setJmxEnabled(true);
              p.setTestWhileIdle(false);
              p.setTestOnBorrow(true);
              p.setValidationQuery("SELECT 1");
              p.setTestOnReturn(false);
              p.setValidationInterval(30000);
              p.setTimeBetweenEvictionRunsMillis(30000);
              p.setMaxActive(100);
              p.setInitialSize(10);
              p.setMaxWait(10000);
              p.setRemoveAbandonedTimeout(60);
              p.setMinEvictableIdleTimeMillis(30000);
              p.setMinIdle(10);
              p.setLogAbandoned(true);
              p.setRemoveAbandoned(true);
              p.setJdbcInterceptors(
                "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
                "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
              DataSource datasource = new DataSource();
              datasource.setPoolProperties(p);
    
              Connection con = null;
              try {
                con = datasource.getConnection();
                Statement st = con.createStatement();
                ResultSet rs = st.executeQuery("select * from user");
                int cnt = 1;
                while (rs.next()) {
                    System.out.println((cnt++)+". Host:" +rs.getString("Host")+
                      " User:"+rs.getString("User")+" Password:"+rs.getString("Password"));
                }
                rs.close();
                st.close();
              } finally {
                if (con!=null) try {con.close();}catch (Exception ignore) {}
              }
          }
    
    }

    作为资源

    下例展示了如何为 JNDI 查找配置资源。

    <Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource"
              factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
              testWhileIdle="true"
              testOnBorrow="true"
              testOnReturn="false"
              validationQuery="SELECT 1"
              validationInterval="30000"
              timeBetweenEvictionRunsMillis="30000"
              maxActive="100"
              minIdle="10"
              maxWait="10000"
              initialSize="10"
              removeAbandonedTimeout="60"
              removeAbandoned="true"
              logAbandoned="true"
              minEvictableIdleTimeMillis="30000"
              jmxEnabled="true"
              jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
                org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
              username="root"
              password="password"
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/mysql"/>

    异步连接获取

    Tomcat JDBC 连接池支持异步连接获取,无需为池库添加任何额外线程。这是通过在数据源上添加一个方法 Future< Connection> getConnectionAsync() 来实现的。为了使用异步获取,必须满足两个条件:
    1. 必须把 failQueue 属性设为 true。
    2. 必须把数据源转换为 org.apache.tomcat.jdbc.pool.DataSource。

    下例就使用了异步特性:

    Connection con = null;
      try {
        Future<Connection> future = datasource.getConnectionAsync();
        while (!future.isDone()) {
          System.out.println("Connection is not yet available. Do some background work");
          try {
            Thread.sleep(100); //simulate work
          }catch (InterruptedException x) {
            Thread.currentThread().interrupt();
          }
        }
        con = future.get(); //should return instantly
        Statement st = con.createStatement();
        ResultSet rs = st.executeQuery("select * from user");

    拦截器

    对于启用、禁止或修改特定连接或其组件的功能而言,使用拦截器无疑是一种非常强大的方式。默认情况下,基于性能方面的考虑,连接池是无状态的。连接池本身所插入的状态是 defaultAutoCommit、defaultReadOnly、defaultTransactionIsolation,或 defaultCatalog(如果设置了这些状态)。这 4 个状态只有在连接创建时才设置。无论这些属性是否在连接使用期间被修改,池本身都不能重置它们。

    拦截器必须扩展自 org.apache.tomcat.jdbc.pool.JdbcInterceptor 类。该类相当简单,你必须利用一个无参数构造函数。

      public JdbcInterceptor() {
      }  

    当从连接池借出一个连接时,拦截器能够通过实现以下方法,初始化这一事件或以一些其他形式来响应该事件。

    public abstract void reset(ConnectionPool parent, PooledConnection con);

    上面这个方法有两个参数,一个是连接池本身的引用 ConnectionPool parent,一个是底层连接的引用 PooledConnection con。

    当调用 java.sql.Connection 对象上的方法时,会导致以下方法被调用:

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

    Method method 是被调用的实际方法,Object[] args 是参数。通过观察下面这个非常简单的例子,我们可以解释如果当连接已经关闭时,如何让 java.sql.Connection.close() 的调用变得无用。

      if (CLOSE_VAL==method.getName()) {
          if (isClosed()) return null; //noop for already closed.
      }
      return super.invoke(proxy,method,args);  

    池启动与停止

    当连接池开启或关闭时,你可以得到相关通知。可能每个拦截器类只通知一次,即使它是一个实例方法。也可能使用当前未连接到池中的拦截器来通知你。

     public void poolStarted(ConnectionPool pool) {
      }
    
      public void poolClosed(ConnectionPool pool) {
      }

    当重写这些方法时,如果你扩展自 JdbcInterceptor 之外的类,不要忘记调用超类。

    配置拦截器

    拦截器可以通过 jdbcInterceptors 属性或 setJdbcInterceptors 方法来配置。拦截器也可以有属性,可以通过如下方式来配置:

    String jdbcInterceptors=
    "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState(useEquals=true,fast=yes)"

    拦截器属性

    既然拦截器也有属性,那么你也可以读取其中的属性值。你可以重写 setProperties 方法。

    public void setProperties(Map

    六、构建

    下面利用 1.6 来构建 JDBC 连接池代码,但它也可以向后兼容到 1.5 运行时环境。为了单元测试,使用 1.6 或更高版本。

    更多的关于 JDBC 用途的 Tomcat 配置范例可参看 Tomcat 文档

    从源代码构建

    构建非常简单。池依赖于 tomcat-juli.jar,在这种情况下,需要 SlowQueryReportJmx。

     javac -classpath tomcat-juli.jar \
            -d . \
            org/apache/tomcat/jdbc/pool/*.java \
            org/apache/tomcat/jdbc/pool/interceptor/*.java \
            org/apache/tomcat/jdbc/pool/jmx/*.java

    构建文件位于 Tomcat 的源代码仓库中。

    为了方便起见,在通过简单构建命令生成所需文件的地方也包含了一个构建文件。

      ant download  (downloads dependencies)
      ant build     (compiles and generates .jar files)
      ant dist      (creates a release package)
      ant test      (runs tests, expects a test database to be setup)

    系统针对 Maven 构建进行组织,但是没有生成发布组件,只有库本身。

    展开全文
  • 通过Loadrunner连接操作Hadoop HDFS

    千次阅读 2017-06-27 14:01:02
    本文以Loadrunner的Java_Vuser脚本为例,来做一次HDFS的文件操作测试,由于LoadRunner 11只支持JDK1.6,所以Hadoop选择的Jar包也只能用Hadoop2.6.0,但是这不影响连接高版本的hadoop-HDFS(本次测试就实现了连接操作...

    本文以Loadrunner的Java_Vuser脚本为例,来做一次HDFS的文件操作测试,由于LoadRunner 11只支持JDK1.6,所以Hadoop选择的Jar包也只能用Hadoop2.6.0,但是这不影响连接高版本的hadoop-HDFS(本次测试就实现了连接操作hadoop2.7下HDFS)。

    1、在loadrunner中新建脚本(本文以LoadRunner11为例),要求选择协议类型为Java->Java Vuser

    2、在Run-time Settings设置JDK路径,由于LoadRunner11不支持jdk1.8,本次测试是拷贝了一份低版本的JDK1.6,所以路径选择固定路径模式,如下所示:


    3、可以上网下载一份Hadoop2.6.0的JAR包(官网和网上都能搜到),我专门准备了一份供大家下载(做了精简,去掉了一些与本次测试无关的Jar包):http://download.csdn.net/detail/smooth00/9881769,将JAR包放到Loadrunner的include目录下或其它指定目录下,并在Run-time Settings中配置Classpath:


    4、在Loadrunner中以java Vuser协议创建脚本,脚本样例如下:

    /*
     * LoadRunner Java script. (Build: _build_number_)
     * 
     * Script Description: 
     *                     
     */
    import java.io.FileInputStream;  
    import java.io.FileNotFoundException;  
    import java.io.FileOutputStream;  
    import java.io.InputStream;  
    import java.io.IOException;  
    import java.io.OutputStream;  
    import java.net.URI;  
    import java.net.URISyntaxException;  
    
    import org.apache.hadoop.conf.Configuration;  
    import org.apache.hadoop.fs.BlockLocation;  
    import org.apache.hadoop.fs.FileStatus;  
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.FSDataOutputStream;  
    import org.apache.hadoop.fs.Path;  
    import org.apache.hadoop.io.IOUtils;  
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    import org.apache.log4j.xml.DOMConfigurator;
    import java.io.File;
    
    import lrapi.lr;
    
    public class Actions
    {
        FileSystem fs = null;
        private Configuration configuration =null;
        private String keyFS ="fs.defaultFS";
        private String keyUser ="hadoop.user";   
    
        //上传文件  测试成功
        // @uploadFile 要上传的本地文件
        // @intputFile 输入到HDFS的文件
        public void testUpload(String uploadFile,String intputFile) throws Exception{  
            InputStream in = new FileInputStream(uploadFile);  
            OutputStream out = fs.create(new Path(intputFile));
            IOUtils.copyBytes(in, out, 1024, true);//in输入源, out输出源头, 1024缓冲区大小 ,true 是否关闭数据流。如果是false,就在finally里关掉  
        } 
           
        //创建文件夹  测试成功  
        public void testMkdir(String dirs) throws IllegalArgumentException, IOException{  
            boolean  flag = fs.mkdirs(new Path(dirs));
            System.out.println(flag);//如果创建目录成功会返回true  
        }
           
        //下载文件  测试成功
        // @outputFile 要下载的HDFS文件
        // @downloadFile 要下载到本地的文件
        public void testDownload(String outputFile,String downloadFile) throws IllegalArgumentException, IOException{  
    	InputStream in = fs.open(new Path(outputFile));//intput.txt
            OutputStream out = new FileOutputStream(downloadFile);//下载到本地路径 以及重命名后的名字  
            IOUtils.copyBytes(in, out, 4096, true);  
        }
           
        //删除文件   测试成功  
        public void testDelFile(String delFile) throws IllegalArgumentException, IOException{  
            boolean flag = fs.delete(new Path(delFile),true);//如果是删除路径  把参数换成路径即可"/a/test4"  inpufile
            //第二个参数true表示递归删除,如果该文件夹下还有文件夹或者内容 ,会变递归删除,若为false则路径下有文件则会删除不成功  
            System.out.println("删除文件 or 路径");  
            System.out.println("delete?"+flag);//删除成功打印true  
        }
          
        //重命名文件   测试成功 
        // @oldFile 要下载的HDFS文件
        // @newFile 要下载到本地的文件
        public void testRename(String oldFile,String newFile) throws IllegalArgumentException, IOException{  
            boolean flag = fs.rename(new Path(oldFile),new Path(newFile));//第一个参数改名为第二个参数  
            String result=flag?"成功":"失败";  
            System.out.println("result of rename?"+result);//删除成功打印true  
        }
           
        //查看文件是否存在     测试成功  
        public void CheckFile(String existFile) throws IllegalArgumentException, IOException{  
            boolean  flag = fs.exists(new Path(existFile));  
            System.out.println("Exist?"+flag);//如果创建目录成功会返回true  
        }
          
        //寻找文件在文件集中位置  测试成功  
        public void FileLoc(String searchFile) throws IllegalArgumentException, IOException{  
            FileStatus  filestatus = fs.getFileStatus(new Path(searchFile));  
            //System.out.println("filestatus?"+filestatus);//如果创建目录成功会返回true  
            BlockLocation[] blkLocations=fs.getFileBlockLocations(filestatus, 0, filestatus.getLen());//文件开始与结束  
              
            int blockLen=blkLocations.length;//块的个数 
    	System.out.println("块数:"+blockLen);
            System.out.println("---------分割线--------");  
            for(int i=0;i<blockLen;i++){  
                String[] hosts=blkLocations[i].getHosts();  
                System.out.println("block_"+i+"location:"+hosts[0]);  
            }  
            System.out.println("---------分割线---------");  
          
        }
          
        //直接在hdfs上创建文件并在其中输入文字   测试成功 
        // @content 要写入文件的文字内容
        // @outputFile 写入的HDFS文件
        public void testCreateTextFile(String content,String outputFile) throws IllegalArgumentException, IOException{  
              
            byte[] buff=content.getBytes();//想要输入内容
            Path path=new Path(outputFile);//文件存放路径及文件名称  /a/test4/javawrite.txt
            FSDataOutputStream outputStream=fs.create(path);  
            outputStream.write(buff, 0, buff.length);  
            System.out.println("输出文件成功");  
          
        }
    
    	public int init() throws Throwable {
    	    //System.setProperty("hadoop.home.dir", "D:\\Program Files\\HP\\LoadRunner\\include\\hadoop\\hadoop-common-2.2.0-bin-master");
    	    //加载日志输出方式
    	    File directory = new File(".");
    	    DOMConfigurator.configure(directory.getCanonicalPath()+"\\log4j.xml");//加载log4j.xml文件
    	    //PropertyConfigurator.configure("E:/study/log4j/log4j.properties");//加载.properties文件
    	    Logger log=Logger.getLogger("org.zblog.test");
    	    System.setProperty("hadoop.home.dir", directory.getCanonicalPath()+"\\hadoop-common-2.2.0-bin-master");
                //初始化 
    	    configuration=new Configuration();
    	    //configuration.set(keyFS,"hdfs://172.17.2.12:8020");
                configuration.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
    	    configuration.set("fs.file.impl", "org.apache.hadoop.fs.LocalFileSystem");
                //configuration.set("fs.hdfs.impl",org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
    	    fs = FileSystem.get(new URI("hdfs://172.16.1.80:8020"), configuration,"hdfs");//hdfs为用户名
    	    //fs = FileSystem.get(URI.create(fsname), configuration, user);
    		return 0;
    	}//end of init
    
    
    	public int action() throws Throwable {
    	    testMkdir("/a//test4");
    	    testCreateTextFile("hello hadoop world!\n","/a/test4/intput.txt");
    	    testUpload("d://textdownload.txt","/a/test4/intput.txt");
    	    testDownload("/a/test4/intput.txt","d://textdownload2.txt");
    	    testRename("/a/test4/intput.txt","/a/test4/intput");
    	    FileLoc("/a/test4/intput");
    	    testDelFile("/a/test4/intput");
    	    
    		return 0;
    	}//end of action
    
    
    	public int end() throws Throwable {
    		return 0;
    	}//end of end
    }
    需要说明的,本次样例脚本中,还引用了hadoop-common-2.2.0-bin-master(主要是因为在windows下开发Hadoop需要用到winutils.exe,本次的目的是为了在Windows下运行以上脚本后,能同时输出hadoop-HDFS运行日志),下载地址为(免积分): http://download.csdn.net/detail/nma_123456/8663763

    5、将下载的hadoop-common-2.2.0-bin-master解压到Loadrnner脚本目录下(hadoop-common-2.2.0-bin-master下一层是bin目录)

    6、同样在Loadrnner脚本目录下创建hadoop的日志配置文件log4j.xml,配置内容如下:

    <?xml version="1.0" encoding="GB2312" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="org.zblog.all" class="org.apache.log4j.RollingFileAppender">
    <!-- 设置通道ID:org.zblog.all和输出方式:org.apache.log4j.RollingFileAppender -->
    <param name="File" value="./all.output.log" /> <!-- 设置File参数:日志输出文件名 -->
    <param name="Append" value="false" /> <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
    <param name="MaxBackupIndex" value="10" />
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%p (%c:%L)- %m%n" /> <!-- 设置输出文件项目和格式 -->
    </layout>
    </appender>
    <appender name="org.zblog.zcw" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="E:/study/log4j/zhuwei.output.log" />
    <param name="Append" value="true" />
    <param name="MaxFileSize" value="10240" /> <!-- 设置文件大小 -->
    <param name="MaxBackupIndex" value="10" />
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
    </layout>
    </appender>
    <logger name="zcw.log"> <!-- 设置域名限制,即zcw.log域及以下的日志均输出到下面对应的通道中 -->
    <level value="debug" /> <!-- 设置级别 -->
    <appender-ref ref="org.zblog.zcw" /> <!-- 与前面的通道id相对应 -->
    </logger>
    <root> <!-- 设置接收所有输出的通道 -->
    <appender-ref ref="org.zblog.all" /> <!-- 与前面的通道id相对应 -->
    </root>
    </log4j:configuration>
    7、一切就绪后,就可以运行脚本了(记住HDFS的连接地址,如hdfs://172.17.2.12:8020和用户要配置正确),运行成功如下所示:




    展开全文
  • 几种常见数据库连接

    万次阅读 2017-06-30 07:54:01
    感觉介绍之前有必要阐述一下连接池的几个概念,有助于后边一些文字的理解。 最原始的数据库使用就是打开一个连接并进行使用,使用过后一定要关闭连接释放资源。由于频繁的打开和关闭连接对jvm包括数据库 都有...
  • li标签内容前面插入图片的一种方法: 选择器: 四个最基本的选择器:id选择器,class选择器,标签选择器,“*”通用选择器,其他的选择器都是基于这四个。 后代选择器:将两个选择器用空格隔开表示后代选择器...
  • [职业交流]《想领导的前面》——领导的思路里找机会 作者:作者金刚心 日期:2011-1-4 11:02:00  我们做过的职场规划和做过的培训以千计;从中受益的职业人有很多服务于世界一流企业中;因为对国内各种体制的...
  • 公司的网站改版要求一个页面显示百度地图.上面要同时显示很多标注点,标注点当然要有提示信息嘛,提示信息也当然要不一样嘛,因为给标注绑定的鼠标事件当你移动鼠标上去的其实循环值已经是最后值了,所以无论你怎么做,...
  • IPC连接

    千次阅读 2014-01-25 09:49:57
    IPC$是Windows系统特有的一项管理功能,是微软公司为了方便用户使用计算机而设计的,主要用来远程管理计算机的。但事实上使用这个功能最多...è 远程计算机上执行命令。 2.1.1 远程文件操作 1.相关知识 (1)什么是I
  • 几种常见数据库连接池的使用比较

    万次阅读 多人点赞 2016-11-23 20:35:32
    感觉介绍之前有必要阐述一下连接池的几个概念,有助于后边一些文字的理解。 最原始的数据库使用就是打开一个连接并进行使用,使用过后一定要关闭连接释放资源。由于频繁的打开和关闭连接对jvm包括数据库 都有...
  • 自定义控件之绘图篇(二):路径及文字

    万次阅读 多人点赞 2014-08-29 16:09:03
    前言:今天项目进入攻关期,他们改Bug要改疯掉了,主管为了激励大家,给大家发了一封邮件,讲到他对项目和学习的理解,一个很好的图形模型,分享给大家,如图下面给出:(不便给出原文,我仅做转述)无论是学习...
  • 我把早上的发的朋友圈文字附于文后,以应景。 周中写了一篇关于socket查找的文章,次日,也就是昨天上午,收到一封反馈邮件,好快,十分高兴能和大家一起进行技术讨论。 这封邮件里,一位朋友提出了一种查询...
  • 微信发送消息中带网页连接

    千次阅读 2015-12-25 15:06:41
    编辑消息: 这个消息带网页连接,浏览网页请点击http://www.baidu.com/>百度网页 其中网址内容一定要有...连接的说明文字(蓝色字,“百度网页”)就会带有网页的超链接,当点击“百度网页”,就会跳转到前面的网址上。
  • 文字检测是文字识别过程中的一个非常重要的环节,文字检测的主要目标是将图片中的文字区域位置检测出来,以便于进行后面的文字识别,只有找到了文本所在区域,才能对其内容进行识别。 文字检测的场景主要分为两种,...
  • 前几天我们又遇到了一个Netty报从连接池获取连接超时异常从而导致整个服务不可用的异常,报的具体异常信息是Exception accurred when acquire channel channel pool:TimeoutException。当时自己看了这个异常信息,有...
  • Axure RP Pro - 相关问题 - Button按钮部件不支持设置文字以及解决方法Axure RPPro中,有很多部件可以设计时设置文字,但是并不支持事件中使用Set Variable and Widget value(s) equalto Values(s)动作设置...
  • 《游戏脚本的设计与开发》-1.2 文字显示[Hello world]

    千次阅读 多人点赞 2013-05-20 06:08:22
    显示一个文字,就是将文字绘制到游戏界面上,而lufylegend.js引擎中,要显示一个文本,只需要将LTextField对象添加到LSprite对象之上。首先,为了便于操作游戏中的所有对象,我们来新建一个“仓库”LScriptArray,...
  • 索引节点、硬连接连接计数 索引节点inode:   Linux为每个文件分配一个称为索引节点的号码inode,可以将inode简单理解成一个指针,它永远指向本文件的具体存储位置。系统是通过索引节点(而不是文件名)来定位...
  • 维持长连接

    千次阅读 2010-04-19 11:03:00
    现成的长连接应用--Connection:keep-alive HTTp协议请求和响应中加入这条就能维持长连接。再封装HTTP消息数据体的消息应用就显的非常简单易用 Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的...
  • 收端控制,因此接收窗口就表示“我能接收多少”,按照这个数字发送,连接独占网络并且带宽无限的 情况下流量是平滑的。接收端的接收窗口将按照自己的能力向前滑动。 然而网络环境不是那么理想的,第
  • PHP连接MySQL的2种方法以及防止乱码

    千次阅读 2007-03-21 20:49:00
    PHP的MySQL配置报错信息:Class mysqli not ...conf/php.ini中,vim用"/php_mysql"搜索到extension=php_mysql.dll,去掉前面的";",同时下面增加extension=php_mysqli.dll;注意后面那个dll多了个i2."/extension_
  • WPF中制作立体效果的文字或LOGO图形

    万次阅读 2008-04-20 20:06:00
    有时,为了美观的需要,我们可能需要应用程序中制作一些看上去很酷的3D效果,比如下面的效果:这是一种立体的纯文字效果,或许你可以网上找到相关工具自动生成图片,但如果是需要生成矢量的XAML图形文件,这样的...
  • Tesseract是惠普布里斯托实验室1985到1995年间开发的一一个开源的OCR引擎,曾经1995 UNLV精确度测试中名列前茅。但1996年后基本停止了开发。2005年,惠普将其对外开源,2006 由Google对Tesseract进行改进、消除...
  • TCP连接的同时打开和同时关闭

    千次阅读 2017-08-06 21:49:29
     在前面的内容中我们介绍了TCP连接管理中最常见的三次握手方式和四次挥手的方式。但是有可能A和B两端同时执行主动打开并连接对方或者同时执行主动关闭连接(尽管发生这种情况的可能性比较低低),这个时候的流程就略...
  • Python连接mysql数据库

    万次阅读 2012-04-25 18:00:24
    前面系统地学习了java连接mysql数据库,现在做python的时候需要用到数据库,于是自己重新整理了一下数据库的知识,并且熟悉了python中MysqlDB模块的功能和函数等接口,现在系统地来总结一下吧: 首先你要做的还是...
  • 运用HTML5进行文字排版详解

    千次阅读 2017-08-17 17:33:08
    1.设置段落样式的标记 标记 功能 &lt;p&gt; 标记来区分段落 容器标记 会换行并增加一个空行 &lt;br&...  让文字按照原始代码的排列方式进行显示 &lt;blockq...
  • 首先我使用xshell远程连接腾讯云时,出现了无法显示中文的情况。 根据以往的经验,试想了一下是否是系统没有中文的语言包。 locale -a查看当前系统所支持的字符集 发现是有中文字符集的,那我们就不需要...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 112,739
精华内容 45,095
关键字:

如何在连接前面加文字