赞
踩
Intent是Android应用里各组件之间通信的重要方式,一个Activity通过Intent来表达自己的意图—想要启动哪个组件(activity,service,broadcasts)。
描述Intent对象要实施的动作,可以调用Intent#setAction()方法来指定action。action值为String类型。
清单文件中也有:
<action android:name="android.intent.action.MAIN" />
常见的action:
Intent对象中用于进行操作的数据,可以调用Intent#setData()或Intent#setDataAndType(),data值一般为Uri类型。
描述Intent对象中的action属性属于哪个类别,也就是设置Intent对象进行某项操作时的约束,可以通过Intent#addCategory()方法设置,category值为String类型。
如清单文件中:
<category android:name="android.intent.category.LAUNCHER" />
用于描述组件能够处理的请求类型(即数据的MIME类型),可以通过Intent#setType()或Intent#setDataAndType()来进行设置。type值为String类型。
描述Intent对象中所使用的组件类名字可以通过Intent#setComponent()方法利用类名进行设定,也可以通过Intent#setClass()方法利用类型对象信息进行设置。当调用组件明确指定了component信息,组件管理服务就不再需要根据action、data、等信息去寻找满足其需求的组件,只需要按照component信息实例化对应的组件作为功能的实现者即可。一但指定了component,intent就变成了单纯的信息载体,只负责传递信息和数据。这种方式通常用于内部组件的互连互通中。component值类型为ComponentName类型。
public Intent setClass(Context packageContext, Class<?> cls) {
mComponent = new ComponentName(packageContext, cls);
return this;
}
public Intent setClassName(String packageName, String className) {
mComponent = new ComponentName(packageName, className);
return this;
}
public Intent setComponent(ComponentName component) {
mComponent = component;
return this;
}
特定应用程序组件(Android四大组件)的标识符。需要在这里封装的两条信息来标识组件:它所在的包(String)和该包中的类(String)名称。
private final String mPackage; private final String mClass; public ComponentName(String pkg, String cls) { if (pkg == null) throw new NullPointerException("package name is null"); if (cls == null) throw new NullPointerException("class name is null"); mPackage = pkg; mClass = cls; } public ComponentName(Context pkg, Class<?> cls) { mPackage = pkg.getPackageName(); mClass = cls.getName(); } public ComponentName(Context pkg, String cls) { if (cls == null) throw new NullPointerException("class name is null"); mPackage = pkg.getPackageName(); mClass = cls; }
以Bundle类的形式存储其他额外的需要的数据。可以通过Intent#putExtras()方法来设置。
public Intent putExtras(Bundle extras) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putAll(extras);
return this;
}
在清单文件中一定见过标签,这就是描述该Activity能够处理哪些Intent的过滤器。一个Activity中可以有一到多组过滤器,每组过滤器通常包括有action、category、type等属性信息。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
/** * Create an empty intent. */ public Intent() { } /** * Copy constructor. */ public Intent(Intent o) public Intent(String action) public Intent(String action, Uri uri) public Intent(Context packageContext, Class<?> cls) public Intent(String action, Uri uri, Context packageContext, Class<?> cls)
//方式一(显式):使用上面第五种构造方法:指定当前activity和要打开的activity
Intent intent=new Intent(this,SecondActivity.class);
//方式二(显式):通过使用Intent#setClass()方法指定当前activity和要打开的activity
Intent intent=new Intent();
intent.setClass(this,SecondActivity.class);
//方式三 (隐式):通过使用Intent#setClassName()方法指定当前activity和要打开的activity
Intent intent=new Intent();
intent.setClassName(this,"包名.SecondActivity");
//或者
intent.setClassName("包名","包名.SecondActivity");
先创建出一个Intent实例不指定其对应的Activity组件,再调用Intent#setAction()等方法设置action、category、type等属性信息。由Android系统根据属性信息选择最适合的Activity去运行这个Intent。兼具弱耦合的特性,更灵活。
一个Activity如果需要隐式跳转,那么在清单文件中必须添加以下子节点
<intent-filter >
<action android:name="com.jeff.action"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
“java.lang.IllegalArgumentException: Service Intent must be explicit”
产生原因:API21以后启动Service的Intent必须为显式否则会抛出异常
解决方法:
Intent eintent = new Intent(createExplicitFromImplicitIntent(this,intent)); /*** * API21以后启动Service的Intent必须为显式否则会抛出异常 * "java.lang.IllegalArgumentException: Service Intent must be explicit" * Android L (lollipop, API 21) introduced a new problem when trying to invoke implicit intent, * "java.lang.IllegalArgumentException: Service Intent must be explicit" * * 该方法可以将隐式Intent转换为显式 * If you are using an implicit intent, and know only 1 target would answer this intent, * This method will help you turn the implicit intent into the explicit form. * * Inspired from SO answer: http://stackoverflow.com/a/26318757/1446466 * @param context * @param implicitIntent - The original implicit intent * @return Explicit Intent created from the implicit original intent */ public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { // Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0); // Make sure only one match was found if (resolveInfo == null || resolveInfo.size() != 1) { return null; } // Get component info and create ComponentName ResolveInfo serviceInfo = resolveInfo.get(0); String packageName = serviceInfo.serviceInfo.packageName; String className = serviceInfo.serviceInfo.name; ComponentName component = new ComponentName(packageName, className); // Create a new intent. Use the old one for extras and such reuse Intent explicitIntent = new Intent(implicitIntent); // Set the component to be explicit explicitIntent.setComponent(component); return explicitIntent; }
//传递几种基本的数据类型:
public Intent putExtra(String name, XXX value)
//将src中的所有extras复制到此intent
public Intent putExtras(Intent src)
//传递Bundle类型的数据
public Intent putExtras(Bundle extras)
//1.首先获取启动这个Activity的intent对象,在Activity类中定义了这样的方法: /** Return the intent that started this activity. */ public Intent getIntent() { return mIntent; } 2.获取到intent对象后使用Intent类中定义的下面两种方法获取传递的数据: //获取所有类型的数据,获取后强制转换类型即可 public Object getExtra(String name) { return getExtra(name, null); } //获取XXX类型的数据 public XXX getXXXExtra(String name) //获取Bundle类型的数据 public Bundle getExtras()
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。