xml中什么类型的组件为盼一般用到哪些结尾“/>” 什么样的组件又是在结尾才“</.....>”

当前位置:
XML注释、迟绑定 COM 及其它
XML注释、迟绑定 COM 及其它
发布日期: 16:51
浏览次数:6013次
标  签:c / c#
文章评分:5.0
操  作:
称号:未设置简介:...
文章概要:
1、我想从某个方法中使用该方法的 XML 说明文档,这可能吗?...
2、我想在运行时访问一个 COM 组件,但我没有对应的 interop 程序集。我还能使用它吗?我曾考虑在需要时动态生成一个程序集,但这 样做似乎有些过度。问题是我正在编写一个.NET的通用工具类,在编译时不知道该 COM 组件的 ProgID。而这个组件实现了 IDispatch 接口。
3、我们的开发团队在整个 Windows Forms 程序中使用了 Debug.Assert。当有一个断言失败时,就会 显示一个断言对话框。我想根据某种环境条件来控制该对话框的显示,让它只在某些特定的环境条件下才被显示,但又不想为此去修改每次对 Assert 的调用。这能做到吗?
更多主题.....
注:此文在 MSDN 杂志上有更新。本文也一并给出。参见:编辑更新。有关更新的详细信息请参照原文。
我想从某个方法中使用该方法的 XML 说明文档,这可能吗?我希望能以下面这样的方式使用它们:
///用法: myApp.exe file1.dat file2.dat … fileN.dat
public static void Main(string [] args)
if (args.Length == 0)
Console.WriteLine(XmlComments.Current.Summary.InnerText);
在 .NET 框架内部有这样的类吗?
C#的编译器可以直接从C#的源代码文件中提取其XML注释。如果在编译时,/doc 命令行选项(或Visual Studio .NET& IDE 中同等选项),被用于指定一个文档目标文件,那么源代码中的所有注释将会被提取出来并按 XML 格式写入该目标文件中。 当这个 XML 文件与编译过的程序集在同一目录时(注意:这个 XML 文档还必须与程序集同名,但扩展名为 .XML),Visual Studio .NET 便能用这个文件显示(IntelliSense:“智能感应”)。到 Visual Studio 2005 推出时,Visual C++ 与 Visual Basic 的编译器都能支持这个特性。
.NET 框架没有提供专门用于采集和处理 XML 注释的类,但 System.Xml 命名空间所提供的 功能可被直接用于完成这样的任务。实际上,在本文附带的源代码中有一个类,借助这个类,你便可以使用你前面描述的语法。
为了获取描述特定类型或类成员的 XML 文档,你首先得找到包含那个文档的 XML 文件。为此,你必须知道该类型或类成员是在哪个程序集里声明的(译注:XML文档里的元素与程序集里的这些元素紧密关联,看看源文件,再看看生成的XML文件就明白了 )。对于给定的 MemberInfo 对象,你可以调用 MemberInfo.DeclaringType() 来获得声明该成员的 Type 对象 (如果你想要描述某个 Type 的文档,你不必获得其 DeclaringType,因为你已经具备一个有效的 Type 对象)。使用该 Type 对象的 Assembly属性 便能找到声明这个类型的程序集,然后,从属性返回的 Assembly 实例通过 Location 属性揭示文件在磁盘上的位置。然后,你可以用 .xml 替换程序集文件的扩展名,并将此 XML 文档从其所在位置加载到 XmlDocument 对象中。需要注意的是,.NET 框架中大多数程序集都是从 GAC(全局程序集缓存——Global Assembly Cache)加载的,而其 XML 文档文件都在运行时目录。如果系统从程序集所在文件夹目录加载 XML 文档失败的话,就再试试从 RuntimeEnvironment.GetRuntimeDirectory() 方法 返回的位置(详情参见上一期的专栏)。
Figure 1 编程实现对 XML 注释的访问
一旦你将程序集的 XML 注释加载到一个 XmlDocument 对象,就可以利用 XPath 表达式找到描述特定 MemberInfo 对象的注释了。其原理如 Figure 1,获取 XmlNode 的代码示例参见 Figure 2。关于如何根据 XML 文档创建 XPath 表达式,请见 Processing the XML File。
我已经创建了一个 XmlComments 类,其构造用 MemberInfo 对象作为参数,此 MemberInfo 对象正是你希望的 XML 注释。 该构造函数获取 XmlNode 以得到成员的注释(如果有的话),并用 XPath 查询解析结果查找节点以及描述概要、方法参数、能被丢出的异常等的节点清单。随后通过 XmlComments& 的公共属性,如:Summary 和 Exceptions 来获得这些节点和节点清单。为了解决你所提出的问题,我添加了一个静态 Current 属性,它使用 StackTrace 类来获取方法调用框架,然后用关联的& MemberInfo 以构造一个 XmlComments 实例。
public static XmlComments Current
get { return new XmlComments(new StackTrace().GetFrame(1).GetMethod()); }
在我写这个东西时遇到了一些难题,其中最重要的一个是属性与事件的存取器(Accessor)方法。存取器没有自己的 XML 注释,所以对于 某个给定的存取器 MethodInfo,我需要存取其父辈 MethodInfo。一种方法是使用简单的串处理从存取器名字解析出属性和事件名(例如,修剪存取器名字的开始部分“get_” 或者“set_”)。我选择了一种简单实用的方法。对于一给定的类型,我利用一张哈希表来存储存取器 MethodInfo 对象到其父辈 MemberInfo 的映射(通过遍历某个 Type 对象中的所有属性和事件来创建,并将所有找到的存取器添加到这张表中)。当需要检查某个方法是否为存取器时,我可以查询这张表;如果 该 MemberInfo 是一个表中键值,那么我不仅可以肯定它是一个存取器,而且还可以立即访问其父类的 MemberInfo,并将其作为参数传递给 GetComments() 方法,如 Figure 2 所示,从而替代该存取器原来的 MethodInfo )
Figure 2 使用XPath获取注释
private XmlNode GetComments(MemberInfo mi)
Type declType = (mi is Type) ? ((Type)mi) : mi.DeclaringT
XmlDocument doc = LoadAssemblyComments(declType.Assembly);
if (doc == null)
// Handle nested classes
string typeName = declType.FullName.Replace("+", ".");
// Based on the member type, get the correct xpath query
switch(mi.MemberType)
case MemberTypes.NestedType:
case MemberTypes.TypeInfo:
xpath = "//member[@name='T:" + typeName + "']";
case MemberTypes.Constructor:
xpath = "//member[@name='M:" + typeName + "." +
"#ctor" + CreateParamsDescription(
((ConstructorInfo)mi).GetParameters()) + "']";
case MemberTypes.Method:
xpath = "//member[@name='M:" + typeName + "." +
mi.Name + CreateParamsDescription(
((MethodInfo)mi).GetParameters());
if (mi.Name == "op_Implicit" || mi.Name == "op_Explicit")
xpath += "~{" +
((MethodInfo)mi).ReturnType.FullName + "}";
xpath += "']";
case MemberTypes.Property:
xpath = "//member[@name='P:" + typeName + "." +
mi.Name + CreateParamsDescription(
((PropertyInfo)mi).GetIndexParameters()) + "']";
case MemberTypes.Field:
xpath = "//member[@name='F:" + typeName + "." + mi.Name + "']";
case MemberTypes.Event:
xpath = "//member[@name='E:" + typeName + "." + mi.Name + "']";
// Unknown member type, nothing to do
// Get the node from the document
return doc.SelectSingleNode(xpath);
当然,上述解决方案只适用于为你自己的应用程序生成 XML 注释。并且需谨记 XML 注释并未被编译进入程序集,而是以独立的 .xml 文件形式存在的 ,也就是说,使用该技术的任何方案都应该测试.xml文件是否存在,是否在正确的位置,是否已正确地命名。
我想在运行时访问一个 COM 组件,但我没有对应的 interop 程序集。我还能使用它吗?我曾考虑在需要时动态生成一个程序集,但这 样做似乎有些过度。问题是我正在编写一个.NET的通用工具类,在编译时不知道该 COM 组件的 ProgID。而这个组件实现了 IDispatch 接口。
Type 类提供了一个方法 GetTypeFromProgID(),正好适用于你的这种情形 (如果你只知道 CLSID,而不是 ProgID,可以用 Type.GetTypeFromCLSID())。将 COM 组件的 ProgID 作为参数调用该方法,它将返回描述该组件的一个 Type 对象。接着利用 Activator 类创建该组件的一个实例,再通过 Type 类的各种方法 (比如 InvokeMember、SetProperty 与 GetProperty)访问这个实例。
为了让上述工作变得更简单些,我创建了一个辅助类,如 Figure 3 所示,简化了常用的操作。看看下面这个例子,这段代码创建了一个 SharePoint.StssyncHandler COM 组件的实例,并 查询其 GetStssyncAppName 方法以确定机器上的哪个程序处理 stssync 协议:
Figure 3 访问迟绑定的COM对象
public class LateBoundComHelper : IDisposable
private Type _
private object _
public LateBoundComHelper(string progId) :
this(Type.GetTypeFromProgID(progId, true))
public LateBoundComHelper(Type t)
if (t == null) throw new ArgumentNullException("t");
_obj = Activator.CreateInstance(t);
public object Invoke(string methodName, params object [] args)
ThrowIfDisposed();
return _type.InvokeMember(methodName,
BindingFlags.InvokeMethod, null, _obj, args);
public object this[string propertyName]
ThrowIfDisposed();
return _type.InvokeMember(propertyName,
BindingFlags.GetProperty, null, _obj, null);
ThrowIfDisposed();
_type.InvokeMember(propertyName, BindingFlags.SetProperty,
null, _obj, new object[]{value});
private void ThrowIfDisposed()
if (_obj == null) throw new ObjectDisposedException(GetType().Name)
public void Dispose()
if (_obj != null)
if (_type.IsCOMObject)
while (Marshal.ReleaseComObject(_obj) > 0);
else if (_obj is IDisposable) ((IDisposable)_obj).Dispose();
using(LateBoundComHelper lb =
new LateBoundComHelper("SharePoint.StssyncHandler"))
string stsSyncHandler = (string)lb.Invoke("GetStssyncAppName");
如果你的系统上安装了Microsoft Outlook 2003,那么在 stsSyncHandler 最可能返回的应该是“Outlook”。
另一方面,.NET 框架的 System.Web 命名空间里也深藏了一个相似的辅助类。使用你最熟悉的反编译或者反汇编工具,可以在其中找到 System.Web.Mail.SmtpMail 类。这个 SmtpMail 类内嵌了一个LateBoundAccessHelper 类,后者提供了针对 Windows NT中的 CDONT.NewMail、Windows 2000 以上版本中的 CDO.Message 的迟绑定访问。
如果基于某些原因你仍然需要利用一个 COM 组件的类型库动态地创建一个程序集,你可以通过调用 System.Runtime.InteropServices.TypeLibConverter 类的 ConvertTypeLibToAssembly() 方法实现之。实际上,.NET 框架 SDK 中的工具 tlbimp.exe 与 tlbexp.exe 就是封装了这个类而实现的(tlbimp.exe 使用了 ConvertTypeLibToAssembly()方法,tlbexp.exe 则使用了ConvertAssemblyToTypeLib()方法 )。该方法的详细使用说明参见 TypeLibConverter.ConvertTypeLibToAssembly Method。
我们的开发团队在整个 Windows Forms 程序中使用了 Debug.Assert。当有一个断言失败时,就会 显示一个断言对话框。我想根据某种环境条件来控制该对话框的显示,让它只在某些特定的环境条件下才被显示,但又不想为此去修改每次对 Assert 的调用。这能做到吗?
如同任何一个编程挑战一样,对这个问题也有多种解决办法。一个可行的方案是从 DefaultTraceListener 派生 来编写自己的跟踪侦听器(Trace Listener)。重写其 Fail()方法,并且只在需要显示断言对话框的地方才调用基类的 Fail()方法。记住,只有在调用代码有UIPermissionWindow.SafeSubWindows 权限,并且在程序的诊断配置中启用了 AssertUIEnabled 设置,DefaultTraceListener 才会显示断言对话框。如果你自定义了跟踪侦听器,你可以 象下面这样编程实现替换 DefaultTraceListener:
System.Diagnostics.Debug.Listeners.Clear();
System.Diagnostics.Debug.Listeners.Add(new MyCustomTraceListener());
或者使用一个象这样的配置文件:
如果你决定用另外的方法并且想在显示断言对话框时不依赖 Debug 或者 TraceListeners 集合,那么一个简便易行的方法就是再次使用 DefaultTraceListener 内建的功能:
new DefaultTraceListener().Fail();
不管在侦听器集合中当前配置了哪些侦听器都会显示这个断言。也请记住:将 Debug 与 Trace 的侦听器集合当做是单独的实体想法是不恰当的。其实,Debug.Listeners 与 Trace.Listeners 两者在内部都封装了TraceInternal.Listeners,因此侦听器被添加到其中某个集合实际上同时也被添加到另一个集合。事实上,Trace 和 Debug 类之间的真正差别是作为参数传递给 ConditionalAttribute 的值被附加给类的每一个方法。这个特性控制着调用现场被编译成目标 MS 中间语言( MSIL )的环境。
我的程序需要在某个缓冲区里保存最后加入的N个对象。我在整个 System.Collections 命名空间中也没能找到合适的类。 请问有没有这种现成的类?.NET 框架中有没有办法复用现成的功能使我的实现变得简单些?
据我所知,System.Collections.Queue 是.NET 框架中最接近于你的要求的类。实际上,仅需增加几行代码就能让它完全符合你的要求,完成你所需的操作。
Queue 类实现了经典的与 FIFO (First In First Out,先进先出)同名的数据结构。在其内部,它维护着一个对象数组和两个用于指示数组头尾的整数。当调用 EnQueue() 方法向队列中增加元素时,它首先会 进行内部检查以确定数组是否有足够的空间容纳新元素。若不能,便会增加数组的容量。当确认数组有足够的空间后,新元素会被添加到由整数指定的尾部位置。随着 表示尾部整数的增长,可能会导致它包合数组的起始位置,这是因为元素在出队后,头指针会增加,从而在数组的起始位置留下一个缺口。(译注:System.Collections.Queue 类使用了环形数组,应该不会出现这样的"假溢出"现象吧?)。
为了实现环形缓冲,你必须要保证队列具备最大的容量,并且决不能超过这个最大值上限。(译注:关于环形缓冲,CodeProject 中有一文,我花了一个小时也没打开。:-P)。一种方案是 改写Enqueue()方法,首先检测是否已达队列容量上限。如果是,只需简单地调用 Dequeue() 方法删除一个元素,然后委托基类继续执行。Figure 4 中的代码展示了基本的实现。注意为了让上述代码更健壮,你还需要改写并实现的其它的一些方法,如 Queue.Clone,它返回一个 Queue 实例 ,我把它作为练习留给你来完成。
Figure 4 实现一个环形缓冲
public sealed class CircularBuffer : Queue
private int _
public CircularBuffer(int capacity) : base(capacity)
if (capacity & = 0)
throw new ArgumentOutOfRangeException(&capacity&);
_capacity =
public override void Enqueue(object obj)
if (base.Count == _capacity) base.Dequeue();
base.Enqueue(obj);
public override void TrimToSize()
throw new NotSupportedException();
我想写一个正则表达式,它能扫描只与“{”和“}”字符组合匹配的字符串(“{”后某处跟随匹配的“}”),但我无法确定表达方式。请问有可能实现吗?比如字符串“abcd{}ef}g”是有效的, 因为有“{}”,而“}{”和“abcd{{ef}g}”则是无效的。寻求帮助!
用数量相等的“{”和“}”匹配整个字符串,而不管它们出现的顺序, 需要一种比正则语法(那些能被正则表达式处理的)更强大的语法,用 CFG(context-free grammars)可以轻松解决。但是.NET 框架中没有提供 相应的解析类。
如果你只是想确定是否有与“{”和“}”字符的合法匹配,那可以写一些简单的代码来遍历串中的没一个字符并手工强制此规则。计数以 0 开始,每次遇到“{”时计数器就加 1,每遇到一个“}”则减1。这样当遍历完整个字符串后,如果计数器为负值,那这个字符串就是未匹配的。若计数器为0,则字符串就是匹配了的。
private bool IsMatch(string str)
int count=0;
for(int i=0; i< str.L i++)
if (str[i] == ''{'') count++;
else if (str[i] == ''}'') count--;
return count == 0;
即便具备支持.NET 框架的 CFG 类,我想其性能也不会比我上面示范的代码好多少, 况且对任何维护该代码的人来说它也很清晰(尤其是加上注释的话)。
[编辑更新-7/20/2004:System.Text.RegularExpressions.Regex 支持用 lookahead 和 lookbehind 修饰符分组构造,这样便支持比正则语法更强大的某些语法(有关这方面的详细信息参见:“Grouping Constructs”)。因此,用数量相等的按适当规则排列的左右大括弧匹配字符串可能的模式如下:
string pattern =
@"^((?\{) | [^\{\}] |" +
@"(?\}))*" +
@"(?(openBracket)(?!))$";
Regex r = new Regex(pattern, RegexOptions.IgnorePatternWhitespace);
不管怎样,前面展示的 IsMatch 方法仍然比等价的 Regex 表现要好。]
我正在编写一个应用程序,它使用 HTTP 请求用户提供的不同 Web 站点的 URLs 地址。但我只想请求本地 Intranet 内的 URL。有没有什么简单易行的方法来实现这种检查?
当强制执行 CAS (Code Access Security)机制时,System.Security.Policy 命名空间提供了一个 由公共语言运行时(CLR)使用的 Zone 类。你可以显式地使用该 Zone 类来实现你所希望的那种检查。
private static bool IsIntranet(Uri url)
System.Security.Policy.Zone zone =
System.Security.Policy.Zone.CreateFromUrl(url.ToString());
return zone.SecurityZone == System.Security.SecurityZone.I
某个区域中的 URL 成员关系是基于你的 IE 配置的。为了对区域进行配置,使用 IE 选项面板中的“安全”标签页。
一个更安全的办法是在一个只允许请求 Intranet URLs 的 CAS 沙盒环境中运行这些 HTTP 请求代码。关于沙盒的详细内容,请参见 Sandboxing code dynamically(译注:我无法访问该Web页)。
有什么疑问或者意见,请给我发Email:.
Stephen Toub 是 MSDN 杂志的技术编辑。
摘自 MSDN Magazine 的 2004 年 6 月刊。此杂志可通过各地的报摊购买,也可以订阅。
最多还可以输入100字
【VIP年会员制套餐】
【C/C++软件工程师实战能力集训大纲】
VC知识库发布了C/C++业界的“本草纲目”
【牛人都在千人一号群! 加群三步走!!!】
第一步:请必须加VC知识库QQ: 为好友;
第二步:请必须关注本站微博:
第三步:申请加入群:.(必须将关注微博截屏发到QQ方可通过!)
【最新2013:】
全部100% VC++源码提供: E-Form++全新大型SCADA & HMI解决方案源码、CAD解决方案源码、Gis解决方案源码 、电力石油化工仿真与图形建模解决方案源码、大量其他高级制图VC++源码下载!
【 新视频发布】
o o o o o o o o o o
在VC环境中除了我们所常用的Dialog、Menu和Bitmap等标准资源类型之外,它还支持自定义资源类型(Custom Resource),我们自定义的资源类型能做些什么呢?呵呵,用处多多。...
本文介绍如何采用GDI+ 通过IMAGE类的序列化实现对图形文件的读取、显示。...
本文介绍了套接字编程的基本知识。...spring笔记_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
文档贡献者
评价文档:
spring笔记
本&#8203;人&#8203;的&#8203;s&#8203;p&#8203;r&#8203;i&#8203;n&#8203;g&#8203;笔&#8203;记
大小:14.06KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢当前位置:
XML注释、迟绑定 COM 及其它
发布日期: 16:27
下载次数:2329
标  签:c / c#
称号:未设置简介:...
1、我想从某个方法中使用该方法的 XML 说明文档,这可能吗?...
2、我想在运行时访问一个 COM 组件,但我没有对应的 interop 程序集。我还能使用它吗?我曾考虑在需要时动态生成一个程序集,但这 样做似乎有些过度。问题是我正在编写一个.NET的通用工具类,在编译时不知道该 COM 组件的 ProgID。而这个组件实现了 IDispatch 接口。
3、我们的开发团队在整个 Windows Forms 程序中使用了 Debug.Assert。当有一个断言失败时,就会 显示一个断言对话框。我想根据某种环境条件来控制该对话框的显示,让它只在某些特定的环境条件下才被显示,但又不想为此去修改每次对 Assert 的调用。这能做到吗?
更多主题.....
最多可以输入100字
o o o o o o o o o o
当一个基于对话框的程序中有相当多的控件时,你一定会想到使用属性页来将这些控件分类放置。本文提供的代码实现了几种可能实现的方案。...本篇内容提取自知乎开发中,有哪些让你觉得相见恨晚的方法、类或接口?,其实有一部是JAVA的,但是在开发中也算常见。大多数的函数自己还是见过的,这里记录一下备忘。同时呢,也推荐一个github项目,里面记录了自己日常开发中见过的比较有用的东西开发中常用的工具、链接
Throwable类中的getStackTrace()方法,根据这个方法可以得到函数的逐层调用地址,其返回值为StackTraceElement[],而在StackTraceElement类中有四个方法getClassName(),getFileName(),getLineNumber(),getMethodName()在调试程序打印Log时非常有用。
int num = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
StackTraceElement[] stackTrace = e.getStackTrace();
for (StackTraceElement element : stackTrace) {
String className = element.getClassName();
int lineNumber = element.getLineNumber();
String fileName = element.getFileName();
String methodName = element.getMethodName();
Log.e("TAG","fileName:"+fileName+" lineNumber:"+lineNumber+" className:"+className+" methodName"+methodName);
UncaughtExceptionHandler接口,再好的代码异常难免,利用此接口可以处理未捕获的异常。比如NullPointerException空指针异常抛出时,用户没有try catch捕获,那么,Android系统会弹出对话框的“XXX程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。
* 异常处理类
* User:lizhangqu()
* Time: 14:48
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static final String TAG = CrashHandler.class.getSimpleName();
private Context mC
private static volatile CrashH
private Thread.UncaughtExceptionHandler defalutH
private DateFormat formatter = new SimpleDateFormat(
"yyyy-MM-dd_HH-mm-ss.SSS", Locale.CHINA);
private CrashHandler(){
* 获得单例
* @return 单例
public static CrashHandler getInstance() {
if (instance==null){
synchronized (CrashHandler.class){
if (instance==null){
instance=new CrashHandler();
public void init(Context context){
mContext=context.getApplicationContext();
defalutHandler=Thread.getDefaultUncaughtExceptionHandler();
// 获取系统默认的UncaughtException处理器
Thread.setDefaultUncaughtExceptionHandler(this);
// 设置该CrashHandler为程序的默认处理器
public void uncaughtException(Thread thread, Throwable ex) {
boolean hasHandle=handleException(ex);
//是否处理
if (!hasHandle && defalutHandler!=null){
defalutHandler.uncaughtException(thread,ex);
//如果用户没有处理则让系统默认的异常处理器来处理
Thread.sleep(5000);
} catch (InterruptedException e) {
Log.e(TAG, "error : ", e);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
private boolean handleException(final Throwable ex){
if (ex==null){
return false;
new Thread(){
public void run() {
Looper.prepare();
ex.printStackTrace();
String err="["+ex.getMessage()+"]";
Toast.makeText(mContext, "程序出现异常,5秒后自动退出", Toast.LENGTH_LONG).show();
Looper.loop();
}.start();
String str = collectDeviceInfo(ex);
// 收集设备参数信息,日志信息
saveCrashInfoToFile(str);
// 保存日志文件
return true;
* 收集设备信息,日志信息
* @param ex Throwable
* @return 收集的信息
private String collectDeviceInfo(Throwable ex){
Log.e(TAG,"collectDeviceInfo:"+ex.getMessage());
StringBuilder builder=new StringBuilder();
return builder.toString();
* 保存出错信息
* @param error 待保存的出错信息
private void saveCrashInfoToFile(String error){
Log.e(TAG,"saveCrashInfoToFile:"+error);
程序入口进行初始化,之后未捕获的异常均由此类处理。
CrashHandler.getInstance().init(this);
Resources类中的getIdentifier(name, defType, defPackage)方法,根据资源名称获取其ID,做UI时经常用到。
* 根据资源名获得资源id
* User:lizhangqu()
* Time: 15:18
public class ResourcesUtil {
public static final String LAYTOUT="layout";
public static final String DRAWABLE="drawable";
public static final String MIPMAP="mipmap";
public static final String MENU="menu";
public static final String RAW="raw";
public static final String ANIM="anim";
public static final String STRING="string";
public static final String STYLE="style";
public static final String STYLEABLE="styleable";
public static final String INTEGER="integer";
public static final String ID="id";
public static final String DIMEN="dimen";
public static final String COLOR="color";
public static final String BOOL="bool";
public static final String ATTR="attr";
//TODO please add other strings by yourself
public static int getResourceId(Context context,String name,String type){
Resources resources=null;
PackageManager pm=context.getPackageManager();
resources=context.getResources();
return resources.getIdentifier(name, type, context.getPackageName());
} catch (Exception e) {
e.printStackTrace();
比如获得主布局的id
ResourcesUtil.getResourceId(getApplicationContext(),"activity_main",ResourcesUtil.LAYTOUT);
View中的isShown()方法,以前都是用view.getVisibility() == View.VISIBLE来判断的,但是与这个函数还是有区别的。也就是只有当view本身和它的所有父容器都是visible时,isShown()才返回TRUE。而平常我们调用if(view.getVisibility() == View.VISIBLE)只是对view本身而不对父容器的可见性进行判断。
集合与数组的转化,Arrays类中的asList(T… array)方法,数组转List集合;反过来List.toArray();
android.text.format.Formatter类中formatFileSize(Context, long)方法,用来格式化文件大小(B → KB → MB → GB)
android.text.format.Formatter.formatFileSize(getApplicationContext(),1024);
//返回1.00KB
android.text.format.Formatter.formatFileSize(getApplicationContext(),1024*1024)
//返回1.00MB
android.media.ThumbnailUtils类,用来获取媒体(、视频)缩略图,该类从Android 2.2开始系统新增,不向下兼容
* 创建一张视频的缩略图
* 如果视频已损坏或者格式不支持可能返回null
* @param filePath 视频文件路径
如:/sdcard/android.3gp
* @param kind kind可以为MINI_KIND或MICRO_KIND
ThumbnailUtils.createVideoThumbnail(filePath,kind);
* 创建一个指定大小的缩略图
* @param source 源文件(Bitmap类型)
* @param width
压缩成的宽度
* @param height 压缩成的高度
ThumbnailUtils.extractThumbnail(source , width, height);
* 创建一个指定大小居中的缩略图
* @param source 源文件(Bitmap类型)
* @param width
输出缩略图的宽度
* @param height 输出缩略图的高度
* @param options 如果options定义为OPTIONS_RECYCLE_INPUT,则回收@param source这个资源文件
* (除非缩略图等于@param source)
ThumbnailUtils.extractThumbnail(source , width, height,options);
格式化字符串,可以使用String类的format(String,Object…)方法,如果要格式化资源文件strings.xml中的字符串,可以使用getResources().getString(int,Object…)方法
String.format("money:¥%.2f",1.00);
&resources&
&string name="format"&money:$%.2f&/string&
&/resources&
getResources().getString(R.string.format,1.00);
View类中的三个方法:callOnClick(),performClick(),performLongClick(),可以直接用于触发View的点击事件,不用我们手动点击才触发;
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.e("TAG", "onClick");
findViewById(R.id.btn).setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
Log.e("TAG", "onLongClick");
return true;
findViewById(R.id.btn).callOnClick();
findViewById(R.id.btn).performClick();
findViewById(R.id.btn).performLongClick();
至于callOnClick()和performClick的区别,相信看过源码后你会一目了然。
* Call this view's OnClickListener, if it is defined.
Performs all normal
* actions associated with clicking: reporting accessibility event, playing
* a sound, etc.
* @return True there was an assigned OnClickListener that was called, false
otherwise is returned.
public boolean performClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
ListenerInfo li = mListenerI
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
return true;
return false;
* Directly call any attached OnClickListener.
Unlike {@link #performClick()},
* this only calls the listener, and does not do any associated clicking
* actions like reporting an accessibility event.
* @return True there was an assigned OnClickListener that was called, false
otherwise is returned.
public boolean callOnClick() {
ListenerInfo li = mListenerI
if (li != null && li.mOnClickListener != null) {
li.mOnClickListener.onClick(this);
return true;
return false;
TextUtils类中的isEmpty(String)方法,判断字符串是否为null或”“,不要再自己写判断字符串非空的代码了。
String str =
String str1 = "";
String str2 = "a";
Log.e("TAG", TextUtils.isEmpty(str)+" "+TextUtils.isEmpty(str1)+" "+TextUtils.isEmpty(str2));
//输出true true false
类似的方法还有TextUtils.isDigitsOnly()是否是纯数字
TextView类中的append(String)方法,添加文本,不要再使用getText()方法拿到旧的字符串再拼接,拼接好了之后再调用setText()方法了
TextView textview= (TextView) findViewById(R.id.tv);
textview.setText("aaa");
textview.append("bbb");
View类中的getDrawingCache()等一系列方法,目前只知道可以用来截图
* / 获取指定Activity的截屏,保存到png文件
* @param activity activity
* @return 截屏Bitmap
private static Bitmap takeScreenShot(Activity activity) {
// View是你需要截图的View
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
// 获取状态栏高度
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.
Log.i("TAG", "" + statusBarHeight);
// 获取屏幕长和高
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay()
.getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
- statusBarHeight);
view.destroyDrawingCache();
DecimalFormat类,用于字串格式化包括指定位数、百分数、科学计数法等
DecimalFormat df=new DecimalFormat("0.0");
df.format(12.34);
System类中的arraycopy(src, srcPos, dest, destPos, length)方法,用来copy数组;Arrays.copyOf()里的一系列方法也是间接调用System.arraycopy()方法
Fragment类中的onHiddenChanged(boolean)方法,使用FragmentTransaction中的hide(),show()时貌似Fragment的其它生命周期方法都不会被调用
调用hide或者show你就会发现fragment的生命周期不走了!onPause方法不调用了!onResume只调用一次!这时此时方法onHiddenChanged派上用场
当fragment隐藏时,该方法会调用传入参数为true表示该fragment被隐藏了,
当fragment调用了show方法后,该方法传入的参数为false,表示该fragment正在显示
所以总结起来,如果使用hide/show方法来控制fragment的使用时,原本需要在onResume以及onPause方法做的事情就可以迁移到onHiddenChanged时进行管理
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if(hidden){
this.onPause();
this.onResume();
Activity类中的onWindowFocusChanged(boolean)方法,使用一个view的getWidth() getHeight() 方法来获取该view的宽和高,返回的值却为0。
如果这个view的长宽很确定不为0的话,那很可能是你过早的调用这些方法,也就是说在这个view被加入到rootview之前你就调用了这些方法,返回的值自然为0.,解决该问题的方法有很多,主要就是延后调用这些方法。可以试着在onWindowFocusChanged()里面调用这些方法。
View类中的getLocationInWindow(int[])方法和getLocationOnScreen(int[])方法,获取View在窗口/屏幕中的位置
TextView tv= (TextView) findViewById(R.id.tv);
int loc[]=new int[2];
tv.getLocationInWindow(loc);
Log.e("TAG",loc[0]+" "+loc[1]);
TextView类中的setTransformationMethod(TransformationMethod)方法,可用来实现“显示密码”功能;
TextView tv= (TextView) findViewById(R.id.tv);
tv.setText("123456");
tv.setTransformationMethod(PasswordTransformationMethod.getInstance());
TextWatcher接口,用来监听文本输入框内容的改变,可以做的事很多
View类中的setSelected(boolean)方法结合android:state_selected=”“用来实现选中效果
Surface设置透明,但是会挡住其它控件
SurfaceView.setZOrderOnTop(true);
SurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
ListView或GridView类中的setFastScrollEnabled(boolean)方法,用来设置快速滚动滑块是否可见,当然前提是item够多
PageTransformer接口,用来自定义ViewPager页面切换动画,用setPageTransformer(boolean, PageTransformer)方法来进行设置
apache提供的一系列jar包:commons-lang.jar,commons-collections.jar,commons-beanutils.jar等,里面很多方法可能是你曾经用几十几百行代码实现过的,但是执行效率或许要差很多,比如:ArrayUtils,StringUtils……
AndroidTestCase类,Android单元测试
Activity类中的onNewIntent(intent)方法,具体看这篇Android:onNewIntent()触发机制及注意事项
Activity.startActivities() 常用于在应用程序中间启动其他的Activity。和startActivity()类似,startActivities也是界面跳转,但是传入的intent是一个数组,也就是说是多个。假设我传入的是两个intent: I1和I2,则调用startActivities之后,直接到I2界面,按返回键,到I1界面。其中到I2的过程中,不会经过I1界面,也就是说,不过存在I1的生命周期之说。
Html.fromHtml() 用于生成一个Html,参数可以是一个字符串.但是它不是很快,所以不要经常去用.取而代之的是请手动构建 Spannable 来替换 Html.fromHtml,但是它对渲染从 web 上获取的文字还是很不错的。
TextView.setError() 在验证用户输入的时候很棒
Build.VERSION_CODES 这个标明了当前的版本号,在处理兼容性问题的时候经常会用到.点进去可以看到各个版本的不同特性
Log.getStackTraceString() 方便的日志类工具,方法Log.v()、Log.d()、Log.i()、Log.w()和Log.e()都是将信息打印到LogCat中,有时候需要将出错的信息插入到数据库或一个自定义的日志文件中,那么这种情况就需要将出错的信息以字符串的形式返回来,也就是使用static String getStackTraceString(Throwable tr)方法的时候。
LayoutInflater.from() 顾名思义,用于Inflate一个layout,参数是layout的id.很多地方都会用到
LayoutInflater.from(getApplicationContext()).inflate(int resource, ViewGroup root, boolean attachToRoot)
ViewConfiguration.getScaledTouchSlop() 使用 ViewConfiguration 中提供的值以保证所有触摸是的交互都统一的。这个方法获取的值表示:用户的手滑动这个距离后,才判定为正在进行滑动.当然这个值也可以自己来决定.但是为了一致性,还是使用标准的值较好。
PhoneNumberUtils.convertKeypadLettersToDigits 顾名思义.将字母转换为数字,类似于T9输入法
String abcd = PhoneNumberUtils.convertKeypadLettersToDigits("abcd");
Log.e("TAG",abcd);
//结果为2223
Context.getCacheDir() 获取缓存数据文件夹的路径,这个路径通常在SD卡上(这里的SD卡指的是广义上的SD卡,包括外部存储和内部存储)Adnroid/data/您的应用程序包名/cache/ 下面.测试的时候,可以去这里面看是否缓存成功.缓存在这里的好处是:不用自己再去手动创建文件夹,不用担心用户把自己创建的文件夹删掉,在应用程序卸载的时候,这里会被清空,使用第三方的清理工具的时候,这里也会被清空。
ArgbEvaluator 用于处理颜色的渐变。在使用动画的时候可能用的比较多。可以看下他的实现
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startV
int startA = (startInt && 24) & 0xff;
int startR = (startInt && 16) & 0xff;
int startG = (startInt && 8) & 0xff;
int startB = startInt & 0xff;
int endInt = (Integer) endV
int endA = (endInt && 24) & 0xff;
int endR = (endInt && 16) & 0xff;
int endG = (endInt && 8) & 0xff;
int endB = endInt & 0xff;
return (int)((startA + (int)(fraction * (endA - startA))) && 24) |
(int)((startR + (int)(fraction * (endR - startR))) && 16) |
(int)((startG + (int)(fraction * (endG - startG))) && 8) |
(int)((startB + (int)(fraction * (endB - startB))));
ContextThemeWrapper 方便在运行的时候修改主题。这里以改变系统自带Dialog字体大小为例
//将一个style的parent设置为@android:style/Theme.Dialog
//修改其中的 &item name="android:textSize"&30sp&/item&
//利用context和该style生成ContextThemeWrapper
//利用ContextThemeWrapper生产Builder对象
ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(MainActivity.this, R.style.dialog);
AlertDialog.Builder builder =
new AlertDialog.Builder(contextThemeWrapper);
Dialog dialog=builder.create();
Space 它是Android 4.0中新增的一个控件,它实际上可以用来分隔不同的控件,其中形成一个空白的区域.这是一个轻量级的视图组件,它可以跳过Draw,对于需要占位符的任何场景来说都是很棒的。
android:layout_width="match_parent"
android:layout_height="10dp"/&
ValueAnimator.reverse() 用在动画中,将动画逆向。
EditText类的setKeyListener(KeyListener)方法,设置DigitsKeyListener类将只能输入数字,通过DigitsKeyListener.getInstance(String accepted)方法即可指定EditText可输入的字符集。
DateUtils.formatDateTime() 用来进行区域格式化工作,输出格式化和本地化的时间或者日期。
android.text.format.DateUtils.formatDateTime(getApplicationContext(),System.currentTimeMillis(), DateUtils.FORMAT_SHOW_DATE|DateUtils.FORMAT_SHOW_YEAR|DateUtils.FORMAT_SHOW_TIME);
Linkify.addLinks() 在Text上添加链接。很实用。比如将TextView中的超链接识别为可点击进入的链接。
TextView tv= (TextView) findViewById(R.id.tv);
Linkify.addLinks(tv,Linkify.WEB_URLS);
StaticLayout 在自定义 View 中渲染文字的时候很实用。
使用Canvas的drawText绘制文本是不会自动换行的,即使一个很长很长的字符串,drawText也只显示一行,超出部分被隐藏在屏幕之外。可以逐个计算每个字符的宽度,通过一定的算法将字符串分割成多个部分,然后分别调用drawText一部分一部分的显示, 但是这种显示效率会很低。
StaticLayout是android中处理文字换行的一个工具类,StaticLayout已经实现了文本绘制换行处理
Activity.onBackPressed() 很方便的管理back键的方法,有时候需要自己控制返回键的事件的时候,可以重写一下。比如加入 “点两下back键退出” 功能。
GestureDetector 用来监听和相应对应的手势事件,比如点击,长按,慢滑动,快滑动,用起来很简单,比你自己实现要方便许多。
ActivityManager.getMemoryClass() 告诉你你的机器还有多少内存,在计算缓存大小的时候会比较有用。
ViewStub 它是一个初始化不做任何事情的 View,但是之后可以载入一个布局文件。在慢加载 View 中很适合做占位符。
SystemClock.sleep() 这个方法在保证一定时间的 sleep 时很方便,通常用来进行 debug 和模拟网络延时。
Thread.sleep()是java提供的函数。在调用该函数的过程中可能会发生InterruptedException异常。
SystemClock.sleep()是android提供的函数。在调用该函数的过程中不会发生InterruptedException异常。
DisplayMetrics.density 这个方法你可以获取设备像素密度,大部分时候最好让系统来自动进行缩放资源之类的操作,但是有时候控制的效果会更好一些.(尤其是在自定义View的时候)。
Pair.create(),这个类在v4包下也存在,内部就两个泛型对象,一个叫first,一个叫second,可以类比map,一个为key,一个为value,但是这个Pair不是key,value,而是一组数据
Fragment.setArguments,因为在构建 Fragment 的时候不建议加参数,所以这是个很好的东西,可以在创建 Fragment 之前设置参数
public class BlankFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public static BlankFragment newInstance(String param1, String param2) {
BlankFragment fragment = new BlankFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
DialogFragment.setShowsDialog ()
这是一个很巧妙的方式,DialogFragment 可以作为Dialog显示。可以参考这篇文章Android 官方推荐 : DialogFragment 创建对话框
FragmentManager.enableDebugLogging () 在需要观察 Fragment 状态的时候会有帮助。可以通过getFragmentManager().enableDebugLogging(true);来提供相关的debug功能。
LocalBroadcastManager 这个会比全局的 broadcast 更加安全,简单,快速。一个简单的应用就是退出程序。
* 全局Application基类
* User:lizhangqu()
* Time: 09:35
public class BaseApplication extends Application {
public final static String ACTION_EXIT_APP = "package.exit";
private static LocalBroadcastManager mLocalBroadcatM
private static Context mC
private static BaseA
public static Context getContext() {
public void onCreate() {
super.onCreate();
instance = this;
mContext = this.getApplicationContext();
CorePageManager.getInstance().init(this);
* 发送本地广播退出程序
public void exitApp() {
Intent intent = new Intent();
intent.setAction(ACTION_EXIT_APP);
intent.addCategory(Intent.CATEGORY_DEFAULT);
BaseApplication.getLocalBroadcastManager().sendBroadcast(intent);
BaseActivity.unInit();
* 获得LocalBroadcastManager对象
* @return LocalBroadcastManager对象
public static LocalBroadcastManager getLocalBroadcastManager() {
if (mLocalBroadcatManager == null) {
mLocalBroadcatManager = LocalBroadcastManager.getInstance(mContext);
return mLocalBroadcatM
public class BaseActivity extends FragmentActivity{
public final static String ACTION_EXIT_APP = "package.exit";
* 仅用于接受应用退出广播,程序退出时有机会做一些必要的清理工作
private BroadcastReceiver mExitReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_EXIT_APP)) {
Log.d(TAG,"exit from broadcast");
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
IntentFilter filter = new IntentFilter();
filter.addAction(Config.ACTION_EXIT_APP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
BaseApplication.getLocalBroadcastManager().registerReceiver(mExitReceiver, filter);
//注册本地广播,接收程序退出广播
Application.registerActivityLifecycleCallbacks 就是注册 Activity 的生命周期的一些回调方法,就是一个方便的工具
Application通过此接口提供了一套回调方法,用于让开发者对Activity的生命周期事件进行集中处理。
以往若需监测Activity的生命周期事件代码,你可能是这样做的,重写每一个Acivity的onResume(),然后作统计和处理。
protected void onResume() {
super.onResume();
//TODO 处理和统计代码
Log.v(TAG, "onResume");
Logger.v(TAG, "onResume");
Logging.v(TAG, "onResume");
ActivityLifecycleCallbacks接口回调可以简化这一繁琐过程,在一个类中作统一处理
android.app.Application.ActivityLifecycleCallbacks 它要求API 14+ (Android 4.0+),在我们自定义的Application注册回调。
public void onCreate() {
super.onCreate();
this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
public void onActivityStopped(Activity activity) {
Logger.v(activity, "onActivityStopped");
public void onActivityStarted(Activity activity) {
Logger.v(activity, "onActivityStarted");
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Logger.v(activity, "onActivitySaveInstanceState");
public void onActivityResumed(Activity activity) {
Logger.v(activity, "onActivityResumed");
public void onActivityPaused(Activity activity) {
Logger.v(activity, "onActivityPaused");
public void onActivityDestroyed(Activity activity) {
Logger.v(activity, "onActivityDestroyed");
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Logger.v(activity, "onActivityCreated");
这里只是使用Log日志工具作简要测试,如需满足较复杂的统计或调试需求时,此法可能会大大减少插入代码量,提高效率,更多详情请看这个项目AndroidLifecyle
versionNameSuffix这个 gradle 设置可以让你在基于不同构建类型的 manifest 中修改版本名这个属性,例如,如果需要在在 debug 版本中以”-SNAPSHOT”结尾,那么就可以轻松的看出当前是 debug 版还是 release 版。
buildTypes {
versionNameSuffix "sample"
-nodpi 在没有特别定义的情况下,很多修饰符(-mdpi,-hdpi,-xdpi等等)都会默认自动缩放 assets/dimensions,有时候我们需要保持显示一致,这种情况下就可以使用 -nodpi。
Activity.recreate () 强制让 Activity 重建
BroadcastRecevier.setDebugUnregister ()什么用不知道,调试用的。
android:weightSum (LinearLayout)这个很有用,在百分比布局没有出来前,基本上就是通过这个属性以及layout_weight属性来间接达到百分比。
android:duplicateParentState (View) 此方法可以使得子 View 可以复制父 View 的状态。比如如果一个 ViewGroup 是可点击的,那么可以用这个方法在它被点击的时候让它的子 View 都改变状态。
android:tileMode (BitmapDrawable)可以指定图片使用重复填充的模式。
android:enterFadeDuration/android:exitFadeDuration (Drawables)此属性在 Drawable 具有多种状态的时候,可以定义它展示前的淡入淡出效果。
android:scaleType (ImageView)定义在 ImageView 中怎么缩放/剪裁图片,一般用的比较多的是centerCrop和centerInside。
Merge此标签可以在另一个布局文件中包含别的布局文件,而不用再新建一个 ViewGroup,对于自定义 ViewGroup 的时候也需要用到;可以通过载入一个带有标签的布局文件来自动定义它的子部件。
AtomicFile通过使用备份文件进行文件的原子化操作的类
ViewDragHelper视图拖动是一个比较复杂的问题。这个类可以帮助解决不少问题。可以参考这篇文章Android ViewDragHelper完全解析 自定义ViewGroup神器
**PopupWindow**Android到处都在使用PopupWindow ,甚至你都没有意识到(标题导航条ActionBar,自动补全AutoComplete,编辑框错误提醒Edittext Errors)。这个类是创建浮层内容的主要方法。
**SparseArray**Map的高效优化版本。推荐了解姐妹类SparseBooleanArray、SparseIntArray和SparseLongArray。在编写通用适配器的时候SparseArray可能会用到
PackageManager.setComponentEnabledSetting()可以用来启动或者禁用程序清单中的组件。对于关闭不需要的功能组件是非常赞的,比如关掉一个当前不用的广播接收器。
SQLiteDatabase.yieldIfContendedSafely()让你暂时停止一个数据库事务, 这样你可以就不会占用太多的系统资源。
Environment.getExternalStoragePublicDirectory()还是那句话,用户期望在SD卡上得到统一的用户体验。用这个方法可以获得在用户设备上放置指定类型文件(音乐、图片等)的正确目录。
Context.getExternalFilesDir()申请了SD卡写权限后,你可以在SD的任何地方写数据,把你的数据写在设计好的合适位置会更加有礼貌。这样数据可以及时被清理,也会有更好的用户体验。此外,Android 4.0 Kitkat中在这个文件夹下写数据是不需要权限的,每个用户有自己的独立的数据存储路径。该API从V8才开始支持。
View.generateViewId()每次我都想要推荐动态生成控件的ID。需要注意的是,不要和已经存在的控件ID或者其他已经生成的控件ID重复。
ActivityManager.clearApplicationUserData() 一键清理你的app产生的用户数据,可能是做用户退出登录功能,有史以来最简单的方式了。以前自己的做法真是不忍直视啊。
ActivityOptions方便的定义两个Activity切换的动画。 使用ActivityOptionsCompat 可以很好解决旧版本的兼容问题。使用ActivityOptionsCompat 类可以很方便的实现Material Design的切换动画
ViewParent.requestDisallowInterceptTouchEvent() Android系统触摸事件机制大多时候能够默认处理,不过有时候你需要使用这个方法来剥夺父级控件的控制权。
Fragment 的 setUserVisibleHint方法,可实现 fragment 对用户可见时才加载资源(延迟加载)
IntentService一个可以干完活后自己去死且不需要我们去管理子线程的Service
Executors. newSingleThreadExecutor()单线程顺序执行的任务队列
**android:animateLayoutChanges=”true”**LinearLayout中添加View的动画的办法,支持通过setLayoutTransition()自定义动画
GradientDrawable渐变,可实现阴影效果
PointF,graphics包中的一个类,我们经常见到在处理Touch事件的时候分别定义一个downX,一个downY用来存储一个坐标,如果坐标少还好,如果要记录的坐标过多那代码就不好看了。用PointF(float x, float y);来描述一个坐标点会清楚很多。
StateListDrawable,定义Selector通常的办法都是xml文件,但是有的时候我们的图片资源可能是从动态获取的,比如很多app所谓的皮肤,这种时候就只能通StateListDrawable来完成了,各种addState即可。
includeFontPadding=”false”,TextView默认上下是有一定的padding的,有时候我们可能不需要上下这部分留白,加上它即可。
onTrimMemory,在Activity中重写此方法,会在内存紧张的时候回调(支持多个级别),便于我们主动的进行资源释放,避免OOM。
Fragment在onAttach方法中接收回调
public void onAttach(Activity activity) {
super.onAttach(activity);
mPageSelectedListener = (PageSelectedListener)
mMenuBtnOnclickListener = (MenuBtnOnClickListener)
mCommitBtnOnClickListener = (CommitBtnOnClickListener)
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + "must implements listener");
通过 WindowManager.addView 在其他app界面添加一个view时,经常会无法显示,特别在miui,emui固件上,需要指定type为LayoutParams.TYPE_TOAST。
Paint.setXfermode(porterDuffXfermode),在ApiDemo里面有专门的介绍,实现了穿透,叠加,覆盖等多种绘制效果,非常实用。在自定义View中用的比较多。
通过View.getDrawingCache()可以获取截图,但是需要setDrawingCacheEnabled(true)频繁使用可能会oom,还有一种方法直接用canvas
Bitmap bm = Bitmap.createBitmap((int) (w * scale), (int) (h*scale), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas();
canvas.setBitmap(bm);
View.draw(canvas);
return bm;
由于fragment的缓存机制决定的。默认情况下,viewpager切换页面时会缓存上一个页面,非相邻页面被销毁,可以使用viewPaper.setOffscreenPageLimit()函数来解决
support library 里的任何东西你都值得去看看
fragment嵌套时,内部fragment的manager通过getChildFragmentManager()获得
布局中,view.bringTofont(),把该view在层叠布局中置于最前面。通样的viewgroup的bringChildtoFont(),都是一样的效果。
版权声明:本文为博主原创文章,未经博主允许不得转载。}

我要回帖

更多关于 为盼一般用到哪些结尾 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信