1、设置当用户触发Notification时所发出的Intent,如果设置 FLAG_ACTIVITY_CLEAR_TOP 与 FLAG_ACTIVITY_NEW_TASK ,而launchMode保持不变(即默认为:standard),则当用户用手点击Notification时,此时匹配到后台的Task,并把在堆栈中对应要启动的Activity之前的所有Activity全部清除掉,并且由于 standard 默认对于新的Intent总是创建新的Activity对象。因此存在于该Task中旧的Activity也会被清除掉,然后在该Task中创建新的Activity对象。
2、设置当用户触发Notification时所发出的Intent,如果设置 FLAG_ACTIVITY_CLEAR_TOP 与 FLAG_ACTIVITY_NEW_TASK,而launchMode设置为singleTop,则当用户用手点击Notification时,同1一样,只是存在于该Task中旧的Activity不会被清除掉,此时Intent传递给已经存在的Activity并不会创建新的Activity。
上面得出的结论,经过返回测试,1是正确的,2却存在着很莫名奇妙的问题
假设现在有个程序X,有2个Activity,分别是 A , B ,其中 A 是 设置了android.intent.action.MAIN的Activity(入口Activity),两者的launchMode都为默认的standard,创建该Intent的代码如下:
1
Intent intent = new Intent(this, A.class);
2
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
很明显我们设置的是当用户点击 Notification 时,应该出现的是 A Activity,但无论如何按home键退出当前Task,并使之成为后台Task,在从程序列表启动该程序总能恢复到Task顶端的Activity给用户,如 当前 B,按home键,在从程序列表启动 X ,这个时候出现的Activity任然是 B,但按照如下的方法操作却会使得从程序列表启动 X,出现的是新创建的A Activity,其中经过Log打印得知下面的所有Activity都在同一个Task中
1、打开程序出现A,从A startActivity 到B,按Home键,点Notification出现A,再从A startActivity 到 B,按Home键,从程序列表打开程序 出现新创建的实例A
2、打开程序出现A,从A startActivity 到B,点Notification出现A,再从A startActivity 到B,按Home键,从程序列表打开程序也出现了新创建的实例A
这里所说的“新创建的实例A”都是创建在同一Task中的新的A Activity实例,也就是说按照以上两种方法,再按返回键,出现的则是 B,再按返回键出现的则是 A。这里我实在想不出为什么会在同一Task中创建一个新的Activity,就算从程序列表打开程序的Intent使用了FLAG_ACTIVITY_NEW_TASK标记,我也不知道为什么,如果有朋友知道,一定要告诉我。
到这里,我开始发现 从程序列表启动 的优越性,因为不管是在什么时候按Home,再次从程序列表启动时,总能返回到Task的栈顶Activity。起初我想过一个办法,便是重载Activity写一个类实现当onResume的时候更新Notification,然后我的所有Activity类都直接从该类继承,使得当按Home 之后总能让Notification记住Task的栈顶Activity,就像QQ一样,但这种方法当然有点牵强,于是我开始看SDK 中 有关Home的Simple,终于发现了如果使用如下的Intent,便不会调用对应的Activity,而是调用Task中的栈顶Activity
view sourceprint?
1
Intent intent = new Intent(Intent.ACTION_MAIN);
2
intent.addCategory(Intent.CATEGORY_LAUNCHER);
3
intent.setClass(this, Main.class);
4
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
除了 setClass 可以换成使用 setClassName 绑定,FLAG_ACTIVITY_RESET_TASK_IF_NEEDED可以不设,其他的选项都缺一不可。设置ACTION_MAIN与CATEGORY_LAUNCHER是把该Intent发给了系统对应创建程序的模块,然后系统该模块根据设定的包与类信息还有flags进行处理。当然所有的Intent工作原理都是这样,只是对 ACTION_MAIN - CATEGORY_LAUNCHAR 的处理较为特殊,使得总是显示Task栈顶的Activity而不是setClass设定的Activity类。
@property declaration 属性
为实例变量指定属性(attributes)的途径, 可让编译好器生成 无泄漏和线程安全的访问实例变量的方法.
@property 就是对应的编译器指令
声明一个与数据成员同名的属性来省去读写函数的声明
声明property的语法为:
@property (参数) 类型 名字;
这里的参数主要分为三类:
读写属性: (readwrite/readonly)
setter语意:(assign/retain/copy)
原子性: (atomicity(nonatomic)
assign/retain/copy 决定了以何种方式对数据成员赋予新值
atomicity的默认值是atomic,读取函数为原子操作。
经常用到的参数是 copy/reain/assign。
在其中选择一个来确定属性的setter如何处理这个属性。很多Objective-C中的object最好使用用retain,一些特别的object(例如:string)使用copy。
assign关键字代表setter直接赋值,而不是复制或者保留它。这种机制非常适合一些基本类型,比如NSInteger和CGFloat,或者你并不直接拥有的类型,比如delegates。
readonly关键字代表setter不会被生成, 所以它不可以和 copy/retain/assign组合使用。
在实现里,只需要
@synthesize mainView;
@synthesize window;
就可代替 繁琐的setter, getter方法, 这样就 可让编译器自动生成读写函数,定义了property, 使用者,可以 点号(.) 来存取属性了。
copy与retain的区别:
Copy其实是建立了一个相同的对象,而retain不是:
比如一个NSString对象,地址为0×1111,内容为@”STR”
Copy到另外一个NSString之后,地址为0×2222,内容相同,新的对象retain为1,旧有对象没有变化
retain到另外一个NSString之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1
也就是说,retain是指针拷贝,copy是内容拷贝。
1、EditText有焦点(focusable为true)阻止输入法弹出
editText=(EditText)findViewById(R.id.txtBody); editText.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { editText.setInputType(InputType.TYPE_NULL); // 关闭软键盘 return false; } });
2、当EidtText无焦点(focusable=false)时阻止输入法弹出
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
转自:http://blog.csdn.net/kmyhy/archive/2010/11/18/6018865.aspx