Android疑难
—隐式Intent匹配原则、Android Studio Clean and Rerun、LayoutInflater、Context
1、隐式Intent匹配原则
1、Intent中只能包含一个Action,可以包含多个Category;
2、清单文件中一个Activity可配置多个IntentFilter, 一个IntentFilter可包含多个
Action,多个Category,但是只能包含一个data;
3、Intent若含有Action,IntentFilter中包含多个Action,只要Intent中的Action与IntentFilter中的任一一个Action匹配,则算匹配成功;
4、Intent中若含有category,则这些category必须属于intentFilter中的category的子集,不管intentFilter中配置了多少category,Intent只需携带其子集数量的category即可匹配。
PS:IntentFilter中必须包含:<categoryAndroid:name="android.intent.category.DEFAULT"/>因为使用隐式意图的Intent中会添加默认的Category,即上图中的category值,如IntentFilter中不添加上图的Category,则匹配不成功,会爆出android.content.ActivityNotFoundException: No Activity found to handle Intent { act=xxxxxxxx }异常,但是我其实不太明白,为什么入口Activity中不需要这个默认的Category,希望有知道的能提点一下。
5、若清单文件中一个Activity配置了多个IntentFilter,Intent只需与其中一个IntentFilter中的内容相匹配即可,但不可跨越多个IntentFilter去匹配。
6、Data包含Scheme,Host,Port,Path和Type五部分,Intent中Data和Type是分开设置的,且会按照设置顺序后设置Type或Data会覆盖前设置的Data或type,如果要让Intent中Data和Type共同存在需要使用setDataAndType(Uri data,String type);的API同时设置。Intent中的Data的5个组成部分必须是IntentFilter中5个部分的自己,才算匹配。
2、Android Studio的Clean and Rerun
新版的 Android Studio 引入了 instant run 功能,也就是俗称的热补丁技术,但是热补丁尚有缺陷有时候会出现莫名其妙的失败和错误,这种情况下直接点击 Run 标签下的 Clean and Rerun 就能重新 rebuild 项目。你退出 Android Studio 然后重新进入 Android Studio 实际上也是一个 Rebuild 过程。
当然也可以直接禁用 Instant Run 功能,在 Setting -> Build、Execution and Deployment -> Instant Run 中取消第一个勾就行
可能造成的错误:Execution failed for task ':app:buildInfoDebugLoader'. > Exception while doing past iteration backup
3、LayoutInflater
LayoutInflater实例:
LayoutInflater layoutInflater = LayoutInflater.from(Context context);
这里的Context一般是Activity实例。
inflate方法:
LayoutInflater中inflate方法两个参数和三个参数的区别如下
inflate方法从大范围来看,分两种,三个参数的构造方法和两个参数的构造方法。在这两类中又有细分,OK,那我们就把各种情况都来演示一遍。
1.三个参数的inflate方法
方法头如下:
[java] view plain copy print?
1. public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
好,这里主要分为三种情况,分别来看
1.1 root不为null,attachToRoot为true
当root不为null,attachToRoot为true时,表示将resource指定的布局添加到root中,添加的过程中resource所指定的的布局的根节点的各个属性都是有效的。比如下面一个案例,我的Activity的布局如下:
[java] view plain copy print?
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent"
6. android:orientation="vertical"
7. android:id="@+id/ll"
8. tools:context="org.sang.layoutinflater.MainActivity">
9. </LinearLayout>
我还有一个布局linearlayout.xml如下:
[java] view plain copy print?
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:id="@+id/ll"
4. android:layout_width="200dp"
5. android:layout_height="200dp"
6. android:background="@color/colorPrimary"
7. android:gravity="center"
8. android:orientation="vertical">
9.
10. <Button
11. android:layout_width="wrap_content"
12. android:layout_height="wrap_content" />
13. </LinearLayout>
我现在想把这个linearlayout.xml布局文件添加到我的activity的布局中,那么我可以这么做:
[java] view plain copy print?
1. @Override
2. protected void onCreate(Bundle savedInstanceState) {
3. super.onCreate(savedInstanceState);
4. setContentView(R.layout.activity_main);
5. LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
6. LayoutInflater inflater = LayoutInflater.from(this);
7. inflater.inflate(R.layout.linearlayout, ll,true);
8. }
小伙伴们注意到,这里我都没写将inflate出来的View添加到ll中的代码,但是linearlayout布局文件就已经添加进来了,这就是因为我第三个参数设置为了true,表示将第一个参数所指定的布局添加到第二个参数的View中。最终显示效果如下:
如果我作死多写这么一行代码,如下:
[java] view plain copy print?
1. protected void onCreate(Bundle savedInstanceState) {
2. super.onCreate(savedInstanceState);
3. setContentView(R.layout.activity_main);
4. LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
5. LayoutInflater inflater = LayoutInflater.from(this);
6. View view = inflater.inflate(R.layout.linearlayout, ll, true);
7. ll.addView(view);
8. }