Archive for January, 2015

作者:AngryFox 分类: Uncategorized January 31st, 2015 暂无评论

HashMap是类,Map是接口,HashMap实现了接口Map,就是说HashMap实现了Map所有的方法。java的ArrayList加入一个对象的时候不是把他复制一份,而是只会记住他的引用.android是移动产品内存有限,为了省内存,android虚拟机与java虚拟机对代码带做了不同的处理。
List是一个接口,而ListArray是一个类。 ListArray继承并实现了List。 List list = new ArrayList();这句创建了一个ArrayList的对象后把上溯到了List。而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性。
List a=new ArrayList();
则a拥有List与ArrayList的所有属性和方法,不会减少
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList优于LinkedList,因为ArrayList可以随机定位,而LinkedList要移动指针一步一步的移动到节点处。(参考数组与链表来思考)
3.对于新增和删除操作add和remove,LinedList比较占优势,只需要对指针进行修改即可,而ArrayList要移动数据来填补被删除的对象的空间。
ArrayList和LinkedList是两个集合类,用于存储一系列的对象引用(references)。例如我们可以用ArrayList来存储一系列的String或者Integer。
ArrayList的内部实现是基于基础的对象数组的,因此,它使用get方法访问列表中的任意一个元素时(random-access),它的速度要比LinkedList快。LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端。
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。

@property (nonatomic, retain)
@property是一个属性访问声明,扩号内支持以下几个属性:
1,getter=getterName,setter=setterName,设置setter与getter的方法名
2,readwrite,readonly,设置可供访问级别
2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题
3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序
4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。在生成getter和setter代码时不需要互斥操作;(注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级)。

实现中用@synthesize来让编译器产生getter和setter:
@property(nonatomic,retain) NSString *test;
@synthesize test
1,这个操作在新版的xcode等于同时声名了成员变量test,并生成其getter\setter方法。
2,@property的retain等参数只是告诉编译器怎么生成(当初我理解成test和self.test是两个不同的指针)。
3,self.test=abc等于使用了@synthesize生成的setter,其过程有进行内存管理,不会造成内存泄漏,而test=abc则直接更改指针指向,所以尽量使用self.来赋值。
4,self.test=nil;等于执行了
[test release];
[test=nil];

retain 是指针拷贝,copy 是内容拷贝

IBOutlet
输出口是使用关键字IBOutlet声明的实例变量。控制器头文件中的输出口声明应如下所示:
@property (nonatomic, retain) IBOutlet UIButton *myButton;
IBOutlet关键字的定义如下所示:
#ifndef IBOutlet
#define IBOutlet
#endif
- (IBAction)doSomething:(id)sender;
就编译器而言,IBOutlet并未执行任何操作。它的唯一作用是告诉Interface Builder,此实例变量将被连接到nib中的对象。你创建的任何需要连接到nib文件中的对象的实例变量都必须以IBOutlet关键字开头。打开Interface Builder时,它会在项目头文件中扫描此关键字,你可以根据这些(且只能根据这些)变量将代码连接到nib。
IBAction
操作是控制器类中的方法。它们也是通过特殊关键字IBAction声明的,该关键字告诉Interface Builder,此方法是一个操作,且可以被某个控件触发。通常,操作方法的声明应如下所示:
- (IBAction)doSomething:(id)sender;

作者:AngryFox 分类: Uncategorized January 29th, 2015 暂无评论

A:透明度
R:红色
G:绿
B:蓝

Bitmap.Config ARGB_4444:每个像素占四位,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位
Bitmap.Config ARGB_8888:每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位
Bitmap.Config RGB_565:每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位
Bitmap.Config ALPHA_8:每个像素占四位,只有透明度,没有颜色。

一般情况下我们都是使用的ARGB_8888,由此可知它是最占内存的,因为一个像素占32位,8位=1字节,所以一个像素占4字节的内存。假设有一张480×800的图片,如果格式为ARGB_8888,那么将会占用1500KB的内存。

作者:AngryFox 分类: Uncategorized January 29th, 2015 暂无评论
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  float velocityY) {
	//dosomething
	returnfalse;
}

捕获到这个动作,分析手势,需要处理好这四个参数MotionEvent e1, MotionEvent e2, float velocityX, float velocityY

 先来看一个例子:
private int verticalMinDistance = 20;
private int minVelocity         = 0;  

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if(e1.getX()- e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {
	//切换Activity
	//Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);
        //startActivity(intent);
        Toast.makeText(this,"向左手势",Toast.LENGTH_SHORT).show();
    }elseif(e2.getX() - e1.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity) {
        //切换Activity
        // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);
        //startActivity(intent);
        Toast.makeText(this,"向右手势",Toast.LENGTH_SHORT).show();
    }
    returnfalse;
}

OnFling的四个参数意思分别为
e1: The first down motion event that started the fling.手势起点的移动事件
e2: The move motion event that triggered the current onFling.当前手势点的移动事件
velocityX: The velocity of this fling measured in pixels per second along the x axis.每秒x轴方向移动的像素
velocityY: The velocity of this fling measured in pixels per second along the y axis.每秒y轴方向移动的像素
鼠标手势相当于一个向量(当然有可能手势是曲线),e1为向量的起点,e2为向量的终点,velocityX为向量水平方向的速度,velocityY为向量垂直方向的速度
if(e1.getX()- e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity)
向量的水平长度(滑了有多长)必须大于verticalMinDistance,并且水平方向速度大于minVelocity。
从而可以如此判断手势是否满足一定的条件从而进行相应响应,也可以根据这个写出更复杂的手势判断。

listenner在重载onTouch()这个函数的时候应该思考的问题:

public
boolean onTouch(View v, MotionEvent event) {
returnmGestureDetector.onTouchEvent(event);
}

查看GestureDetector类的onTouchEvent的源码就能知道,进入该函数后会进入case MotionEvent.ACTION_UP这个路径,从而调用onFling函数。

作者:AngryFox 分类: Uncategorized January 29th, 2015 暂无评论

首先,在Android系统中,每一次手势交互都会依照以下顺序执行。
1. 接触接触屏一刹那,触发一个MotionEvent事件。
2. 该事件被OnTouchListener监听,在其onTouch()方法里获得该MotionEvent对象。
3. 通过GestureDetector(手势识别器)转发次MotionEvent对象至OnGestureListener。
4. OnGestureListener获得该对象,听根据该对象封装的的信息,做出合适的反馈。
这个顺序可以说就是手势交互的原理,下面一同来了解一下MotionEvent、GestureDetector和OnGestureListener。
MotionEvent: 这个类用于封装手势、触摸笔、轨迹球等等的动作事件。其内部封装了两个重要的属性X和Y,这两个属性分别用于记录横轴和纵轴的坐标。
GestureDetector: 识别各种手势。
OnGestureListener: 这是一个手势交互的监听接口,其中提供了多个抽象方法,并根据GestureDetector的手势识别结果调用相对应的方法。
下面我再通过一个切换图片的代码示例,演示一下手势交互的实现,让大伙对上面的执行顺序,以及各手势动作的区分有一个更加深刻的了解和记忆。
首先,提供一个只有ImageView的布局文件——main.xml。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"> 

 <ImageView android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"/>
</LinearLayout>

然后,完成我们的Activity,因为要监听触摸屏的触摸事件和手势时间,所以该Activity必须实现OnTouchListener和OnGestureListener两个接口,并重写其中的方法。

public class MainActivity extends Activity implements OnTouchListener,
		OnGestureListener {

	// 创建一个用于识别收拾的GestureDetector对象waiyuwu.blogcn.com
	private GestureDetector detector = new GestureDetector(this);
	// 定义一个数组,用于放漂亮的女孩
	int[] girls = new int[] { R.drawable.girl1, R.drawable.girl2,
			R.drawable.girl3 };
	// 定义数组下标,以方便观看各个女孩
	private int index;
	private ImageView image;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		image = (ImageView) findViewById(R.id.image);
		// 设置一个初始显示的girl吧
		image.setImageResource(girls[index]);
		// 监听这个ImageView组件上的触摸屏时间
		image.setOnTouchListener(this);
		// 下面两个要记得设哦,不然就没法处理轻触以外的事件了,例如抛掷动作。
		image.setLongClickable(true);
		detector.setIsLongpressEnabled(true);
	}// 用于呼喊下一个女孩的方法

	public void goNext() {
		index++;
		index = Math.abs(index % girls.length);
		image.setImageResource(girls[index]);
	}

	// 重写OnTouchListener的onTouch方法
	// 此方法在触摸屏被触摸,即发生触摸事件(接触和抚摸两个事件,挺形象)的时候被调用。
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		detector.onTouchEvent(event);
		return true;
	}

	// 在按下动作时被调用
	@Override
	public boolean onDown(MotionEvent e) {
		return false;
	}

	// 在抛掷动作时被调用
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		// velocityX表示横向的移动,根据手指移动的方向切换女孩
		if (velocityX < 0) {
			goNext();
		} else if (velocityX > 0) {
			goPrevious();
		}
		return false;
	}

	// 用户呼唤上一个女孩的方法
	public void goPrevious() {
		index--;
		index = Math.abs(index % girls.length);
		image.setImageResource(girls[index]);
	}

	// 在长按时被调用
	@Override
	public void onLongPress(MotionEvent e) {
	}

	// 在滚动时调用
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		return false;
	}

	// 在按住时被调用
	@Override
	public void onShowPress(MotionEvent e) {
	}

	// 在抬起时被调用
	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		return false;
	}

按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。
抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。
长按(onLongPress): 手指按在持续一段时间,并且没有松开。
滚动(onScroll): 手指在触摸屏上滑动。
按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。
抬起(onSingleTapUp):手指离开触摸屏的那一刹那。
任何手势动作都会先执行一次按下(onDown)动作。
长按(onLongPress)动作前一定会执行一次按住(onShowPress)动作。
按住(onShowPress)动作和按下(onDown)动作之后都会执行一次抬起(onSingleTapUp)动作。
长按(onLongPress)、滚动(onScroll)和抛掷(onFling)动作之后都不会执行抬起(onSingleTapUp)动作。

作者:AngryFox 分类: Uncategorized January 29th, 2015 暂无评论

Bitmap类都有哪些是必须要掌握的,Paint类是我们必须要掌握的。p.setAlpha(0×80);括号里的0×00表示的就是完全透明。要是0xff那就表示不透明。ascent 表示到基准线之上的距离、descent 表示到基准线之下的距离

想读取本地项目里的资源图片,但又不能用到R文件。
几种读取Bitmap的方法。

   1.以文件流的方式,假设在sdcard下有 test.png图片

FileInputStream fis = new FileInputStream("/sdcard/test.png");
Bitmap bitmap  = BitmapFactory.decodeStream(fis);
   2. 以R文件的方式,假设 res/drawable下有 test.jpg文件
 Bitmap  bitmap = BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable.test);

  3.以ResourceStream的方式,但不用到R文件。
  Bitmap.bitmap=BitmapFactory.decodeStream(getClass().getResourceAsStream(“/res/drawable/test.png”));

还有一种情况值得考虑的,就是当图片资源太大的适合,会出现内存溢出。如何解决呢?

在使用方法decodeFile()/decodeResource()时,都可以指定一个BitmapFacotry.Options。
利用Options的下列属性,可以指定decode的选项:
inPreferredConfig 指定decode到内存中,手机中所采用的编码,可选值定义在Bitmap.Config中。缺省值是ARGB_8888。
inJustDecodeBounds 如果设置为true,并不会把图像的数据完全解码,亦即decodeXyz()返回值为null,但是Options的outAbc中解出了图像的基本信息。
inSampleSize 设置decode时的缩放比例。

//以上代码可以优化内存溢出,但它只是改变图片大小,并不能彻底解决内存溢出。
经过图像变换之后的Bitmap里的数据可以保存到图像压缩文件里(JPG/PNG)。Bitmap.compress()方法的参数format可设置JPEG或PNG格式;quality可选择压缩质量;fOut是输出流(OutputStream),这里的FileOutputStream是OutputStream的一个子类。

扩展:

http://dengyin2000.iteye.com/blog/1328031

http://qianxunniao.iteye.com/blog/1219178

作者:AngryFox 分类: Uncategorized January 21st, 2015 暂无评论

android:scaleType可控制图片的缩放方式,示例代码如下:

<ImageView android:id="@+id/img"
     android:src="@drawable/logo"
     android:scaleType="centerInside"
    android:layout_width="60dip"
    android:layout_height="60dip"
    android:layout_centerVertical="true"/>

说明:centerInside表示按比例缩放图片,使得图片长 (宽)的小于等于视图的相应维度。

注意:控制的图片为资源而不是背景,即android:src=”@drawable/logo”,而非android::background=”@drawable/logo”,我就笨笨地犯了这个低级错误,导致错怪人家scaleType不起作用。程序中动态加载图片也类似,如:应该imgView.setImageResource((Integer)mData.get(position).get(“img”));而非imgView.setBackgroundResource((Integer)mData.get(position).get(“img”));

附:更详细的scaleType说明:

CENTER /center 在视图中心显示图片,并且不缩放图片

CENTER_CROP / centerCrop 按比例缩放图片,使得图片长 (宽)的大于等于视图的相应维度

CENTER_INSIDE / centerInside 按比例缩放图片,使得图片长 (宽)的小于等于视图的相应维度

FIT_CENTER / fitCenter 按比例缩放图片到视图的最小边,居中显示

FIT_END / fitEnd 按比例缩放图片到视图的最小边,显示在视图的下部分位置

FIT_START / fitStart 把图片按比例扩大/缩小到视图的最小边,显示在视图的上部分位置

FIT_XY / fitXY 把图片不按比例缩放到视图的大小显示

MATRIX / matrix 用矩阵来绘制

作者:AngryFox 分类: Uncategorized January 5th, 2015 暂无评论
<?php $array=array("lucy"=-->1983,"lilei"=>1982,"hanmeimei"=>1981);
foreach($array as $k=>$v){
         print current($array)."\n";
}

运行:
<?php $array=array("lucy"=-->1983,"lilei"=>1982,"hanmeimei"=>1981);
foreach($array as $k=>$v){
         print current($array)."\n";
         print next($array);
}

这段运行结果是 1982 1982 1982相信很多同学没猜到吧
hashTable的内部指针:HashTable这个结构体 定义了一个pInternalPointer成员变量,这个变量 指向当前的成员。只有有了个这个成员变量,才能做数组的next(),prev(),end(),reset()等操作。reset() 操作就是将当前数组的HashTable的pInternalPointer 指向链表头部.
现在我们简单整理了下FE_FETCH的逻辑:

  1. 取当前的数组的HashTable;
  2. 如果当前HashTable的内部指针跟opcode.fe.pos 记录的指针不一样,就把HashTable的指针指向这一个;
  3. 取出当前位置的数据,如果失败跳出循环;
  4. 如果数组的key也被用到,当前的key也存一下;
  5. 调用zend_hash_move_forward,将HashTable的内部指针前移一位;
  6. 将内部指针的位置复制给opcode.fe.pos。


现在我们清楚了,在foreach每次循环时,调用的是FE_FETCH 这个opcode,这个操作实际上将当前的 HashTable的指针是跟opcode.fe.pos绑定了,即便用户在foreach的代码体中间修改当前的内部指针,也是 不管用的,因为接下来再一次循环时,数组的内部指针又被修改到和opcode.fe.pos一致了。

$mates = array("lucy","lilei","hanmeimei");
while($mate  = each($mates)){
    echo $mate["value"]."\n";
    $x = $mates;//这一行代码导致了死循环;
}

这个会死循环,相信很多人也没猜到吧
数据赋值给另一个变量时,会导致一个副作用:数组的内部指针会被重置(就跟调用了reset一样);
foreach开始会重置数组的内部指针,每次循环时会同步指针,所以,foreach不会出现死循环的情况.
PHP引入了FE_RESET,FE_FETCH来实现foreach,中间还悄悄地生成了一个临时变量;但是却只用了一个JMP,一个JUMPZ就搞定了while.while没有引入特殊的OPCODE!

set_exception_handler(array(“Myexception”,”exceptionHandler”));
set_error_handler(array(“Myexception”,”errorHandler”));
register_shutdown_function(array(“Myexception”,”shutdownHandler”));

如果是使用ISAPI的方式来运行PHP就必须用Thread Safe(线程安全)的版本;而用FastCGI模式运行PHP的话就没有必要用线程安全检查了,用None Thread Safe(NTS,非线程安全)的版本能够更好的提高效率。

在支持 DTrace 动态跟踪的平台上,可以配置 PHP 打开 DTrace 静态探针。
AOP编程,也叫做面向切面编程,是一种非倾入式编程的方法,采用外部注入的方式来取代嵌入代码。可以实现非常好的模块低耦合。