当前位置: 编程技术>移动开发
本页文章导读:
▪NSString惯用方法 NSString常用方法
03
+(id)stringWithString:nsstring //
创建一个新字符串,并将其设置为nsstring变量值
06
-(id)initWithContentsOfFile:path
encoding:enc error:err //
返回一个文件里的字符串
.........
▪ 深入了解 Context 深入理解 Context什么是Context?
想必大家都不陌生,在 Android 开发中离不开 Context 调用各种跟系统有关的 API 都必须用到 Context 。我们可以将她理解为上下文环境,大概就是里面存储一堆全局.........
▪ OpenGL ES2学习笔记(8)- Varying变量 OpenGL ES2学习笔记(8)-- Varying变量上一篇文章里绘制的三角形,颜色都是写死在Fragment Shader里的,这篇文章介绍如何把颜色写到顶点数据里并且在Shader里使用Varying变量实现颜色插值。
实例代.........
[1]NSString惯用方法
来源: 互联网 发布时间: 2014-02-18
NSString常用方法
01
*
NSString 字符串对象的方法
02
+(id)string //
创建一个新的字符串
03
+(id)stringWithString:nsstring //
创建一个新字符串,并将其设置为nsstring变量值
04
+(NSString
*) stringWithFormat:format, arg, arg1,arg2... 、、 格式化一个字符串到变量
05
-(id)<span
>stringByAppendingFormat:string //
组合字符串并格式化</span> -(id)initWithString:nsstring // 将新分配的字符串设置为nsstring
06
-(id)initWithContentsOfFile:path
encoding:enc error:err //
返回一个文件里的字符串
07
-(id)initWithContentsOfURL:url,
encoding:enc error:err //
返回一个url里的字符串,url参数,编码参数,错误信息
08
-(NSUInteger)length //
返回字符串的长度
09
-(unichar)
characterAtIndex:i //
返回索引为i的unicode字符
10
-(NSString
*)substringFormIndex:i //
返回从i开始到结尾的字符串
11
-(NSString
*) substringWithRange:range //
根据指定的范围返回字符串
12
-(NSString
*) substringToIndex:i //
从开始一直到索引i的字符串
13
-(NSComparator
*) caseInsensitiveCompare:nsstring //
比较两个字符串,忽略大小写
14
-(NSComparator
*)compare:nsstring //
比较两个字符串
15
-(BOOL)hasPrefix:Nsstring //
测试字符串是否nsstring开始
16
-(BOOL)hasSubfix:nsstring //
测试字符串是否以nsstring结尾
17
-(BOOL)isEqualToString:nsstring //
测试两个字符串是否相等
18
-(NSString
*)capializedString //
返回每个单词的首字母大写,其他字母小写
19
-(NSString
*) uppercaseString //转大写
20
-(NSString
*) lowercaseString //
转小写
21
-(const *char *)
UTF8String //
返回utf8 C字符串样式
22
-(double)
doubleValue //
转为double的字符串
23
-(float)
floatValue //
返回字符串表示的双精度点数
24
-(NSInteger)integerValue //
返回字符串的NSinteger整数标识
25
-(int)intValue //
返回转换为整数的字符串
26
27
NSMutableString
常用方法
28
+(id)stringWithCapacity:size //
创建一个初始化包含size的字符串
29
-(id)intiWithCapacity:size //
使用初始容量为size的字符串来初始化字符串
30
-(void)setString:nsstring //
将字符串设置为nsstring
31
-(void)appendString:nsstring //
在末位附加字符串nsstring
32
-(void)deleteCharactersInRange:range //
删除置顶的range中的字符
33
-(void)insertString
nstring atIndex:i //
以索引i为七点位置插入nsstring
34
-(vvoid)replaceCharactersInRange:range
WithString:nsstring //
使用nstring 替换range指定的字符
35
-(void)replaceOccurrencesofString:nsstring
withString:nstring2 options:opts range:range //
在置顶范围内用range中的nsstring2 替换所有的nsstring 1
36
//
opts 选项组合 NSBackwardsSearch 查找从范围尾部开始 太长了,还是看手册把
[2] 深入了解 Context
来源: 互联网 发布时间: 2014-02-18
深入理解 Context
什么是Context?
Context 哪里来的?
有哪几种 Context?
Activity :刚刚我们已经分析 Service :也是继承自 ContextWrapper 跟 Activity 一样 BroadcastReceiver : onReceiver(Context context ) Application:
什么是Context?
想必大家都不陌生,在 Android 开发中离不开 Context 调用各种跟系统有关的 API 都必须用到 Context 。我们可以将她理解为上下文环境,大概就是里面存储一堆全局变量,这些变量在调用系统 API 时需要用到。文字始终难以表达我想说的,咱们来分析原理吧!
开发 Android 应用必须得有一个 Activity ,然后在你的 Activity 里面调用各种系统 API 比如,
String string = getString(R.string.app_name);
这行代码看似简单,但是如果不让你在 Activity 中调用你该怎么获取这个 string ?
Context context; context.getString(R.string.app_name);
你需要一个 Context 对象,那在 Activity 中为何不需要呢?
答案是,Activity 本来就是一个 Context 他继承自 Context,你打开 Activity 可以知道他的继承顺序如下:
Activity -> ContextThemeWrapper -> ContextWrapper -> Context
Context 是一个抽象类,所有方法都没实现,ContextWrapper 实现了所有方法,但是他只是一个代理,打开源码你可以看到他是这样的:
@Override public AssetManager getAssets() { return mBase.getAssets(); } @Override public Resources getResources() { return mBase.getResources(); }
他仅仅调用 mBase 的方法,(这种在设计模式里叫 代理模式 Proxy ),看来我们得弄清楚这个 mBase 哪来的了!
查看源码你会发现只有2个地方设置了 mBase,
public ContextWrapper(Context base) { mBase = base; } /** * Set the base context for this ContextWrapper. All calls will then be * delegated to the base context. Throws * IllegalStateException if a base context has already been set. * * @param base The new base context for this wrapper. */ protected void attachBaseContext(Context base) { if (mBase != null) { throw new IllegalStateException("Base context already set"); } mBase = base; }一是构造函数,一是 attachBaseContext 。
我们先来分析构造函数!Activity 继承自她,所以分析得 Activity 怎么创建的,由于 Activity 的创建过程比较复杂,而此篇重点不是他,所有我在这里直接给出结果,Activity 创建的时候调用的是无参数构造函数。所以 mBase 不是来自构造函数,那就是来自 attachBaseContext 了,下面我们来分析 Activity 在哪里调用了 attachBaseContext()
方法:
查阅 Activity 源码可以找到一处调用
final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config) { attachBaseContext(context);就是 Activity.attach 方法,此方法在 framework 创建 Activity 的时候调用的,要知道这个 context 参数是什么,我们得从 framework 代码去看,
代码:android.app.ActivityThread
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); } catch (Exception e) { } try { if (activity != null) { ContextImpl appContext = new ContextImpl(); appContext.init(r.packageInfo, r.token, this); appContext.setOuterContext(activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config);看到了,context 就是此处的 appContext 他是 ContextImpl 对象,好了,现在我们知道 ContextImpl 才是真正的实现者了。
所以 getString() 的真正调用是 ContextImpl.getResource.getString() ,getString() 的真正实现在 Resource (android.content.res.Resources) 。
记住所有 Context 真正实现都是 ContextImpl
Activty、Service 的 Context 都是每次创建的,而不是全局唯一,所以不要将 Activity 、Service 当做全局 Context 引用,这样会导致 Activity 无法销毁,一直被引用者。
那么什么样的 Context 才能做全局引用呢?
答案是:Application ,如果你没有自定义的 Application 怎么获取这个 Context 呢,你会发现 Context 有一个 getApplicationContext()
方法,他在 ContextImpl 的实现如下:
android.app.ContextImpl
@Override public Context getApplicationContext() { return (mPackageInfo != null) ? mPackageInfo.getApplication() : mMainThread.getApplication(); }
android.app.LoadedApk
Application getApplication() { return mApplication; }
这个mApplication 对象就是程序的 Application 。所以你可以把他强转成你自定义的 Application
[3] OpenGL ES2学习笔记(8)- Varying变量
来源: 互联网 发布时间: 2014-02-18
OpenGL ES2学习笔记(8)-- Varying变量
上一篇文章里绘制的三角形,颜色都是写死在Fragment Shader里的,这篇文章介绍如何把颜色写到顶点数据里并且在Shader里使用Varying变量实现颜色插值。
实例代码和效果把下面的脚本复制到OpenGL Console里:
import java.nio.ByteBuffer import java.nio.ByteOrder import javax.media.opengl.GL def vertexShaderCode = """ attribute vec4 a_Position; attribute vec4 a_Color; varying vec4 v_Color; void main() { gl_Position = a_Position; v_Color = a_Color; } """ def fragmentShaderCode = """ precision mediump float; varying vec4 v_Color; void main() { gl_FragColor = v_Color; } """ def shaderProgram = glob.compileAndLink(vertexShaderCode, fragmentShaderCode) def aPositionLocation = shaderProgram.getAttribLocation("a_Position") def aColorLocation = shaderProgram.getAttribLocation("a_Color") shaderProgram.use() def BYTES_PER_FLOAT = 4 def POSITION_ELEMENT_COUNT = 2 def COLOR_ELEMENT_COUNT = 3 def STRIDE = (POSITION_ELEMENT_COUNT + COLOR_ELEMENT_COUNT) * BYTES_PER_FLOAT def POINT_COUNT = 3 def vertices = [ //x y r g b 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, 1.0f, ] as float[] def vertexData = ByteBuffer .allocateDirect(vertices.length * BYTES_PER_FLOAT) .order(ByteOrder.nativeOrder()) .asFloatBuffer() vertexData.put(vertices) vertexData.position(0) gl.glVertexAttribPointer(aPositionLocation, POSITION_ELEMENT_COUNT, gl.GL_FLOAT, false, STRIDE, vertexData) gl.glEnableVertexAttribArray(aPositionLocation) vertexData.position(POSITION_ELEMENT_COUNT) gl.glVertexAttribPointer(aColorLocation, COLOR_ELEMENT_COUNT, gl.GL_FLOAT, false, STRIDE, vertexData) gl.glEnableVertexAttribArray(aColorLocation) gl.glClear(gl.GL_COLOR_BUFFER_BIT) gl.glDrawArrays(gl.GL_TRIANGLES, 0, POINT_COUNT)效果: 顶点颜色属性
先来看看Vertex Shader代码:
attribute vec4 a_Position; attribute vec4 a_Color; varying vec4 v_Color; void main() { gl_Position = a_Position; v_Color = a_Color; }现在有两个vec4类型的attribute变量,一个代表顶点的位置(xyzw),一个代表颜色(rgba)。我画了个示意图:
def BYTES_PER_FLOAT = 4 def POSITION_ELEMENT_COUNT = 2 def COLOR_ELEMENT_COUNT = 3 def STRIDE = (POSITION_ELEMENT_COUNT + COLOR_ELEMENT_COUNT) * BYTES_PER_FLOAT def POINT_COUNT = 3 def vertices = [ //x y r g b 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, 1.0f, ] as float[]除了位置(x和y坐标)外,我们把颜色(rgb)也放到了数组里,如下图所示:
def shaderProgram = glob.compileAndLink(vertexShaderCode, fragmentShaderCode) def aPositionLocation = shaderProgram.getAttribLocation("a_Position") def aColorLocation = shaderProgram.getAttribLocation("a_Color") shaderProgram.use() ... vertexData.position(0) gl.glVertexAttribPointer(aPositionLocation, POSITION_ELEMENT_COUNT, gl.GL_FLOAT, false, STRIDE, vertexData) gl.glEnableVertexAttribArray(aPositionLocation) vertexData.position(POSITION_ELEMENT_COUNT) gl.glVertexAttribPointer(aColorLocation, COLOR_ELEMENT_COUNT, gl.GL_FLOAT, false, STRIDE, vertexData) gl.glEnableVertexAttribArray(aColorLocation)上面这段代码把Vertex Shader和顶点数据联系在了一起:
Vertex Shader和Fragment Shader都定义了一个vec4类型的Varying变量,这个变量将Vertex和Fragment Shader连接了起来。Vertex Shader把顶点的颜色属性传递给varying变量(v_Color = a_Color;),然后OpenGL会对其进行插值,这样我们就可以在Fragment Shader里使用插值后的变量了(gl_FragColor = v_Color;)。
最新技术文章: