Intent 的作用

Intent 的作用 主要作为启动以及连接 Activity、 Service 或是 BroadcastReceiver 的桥梁。

context.startActivity(aIntent)

context.sendBroadcast(aIntent)

context.startService(aIntent)

对于Activity Service 继承自 Context,自然可以调用上面的方法, 而 BroadcastReceiver 由于使用时 调用的是 onReceive(context, intent), 所以也是可以调用上述方法。也就是这三个控件可以相互启动 把自己包装好的 intent 发给对方(intent 中可以存放数据 (putExtra))这时也是起到了通信的作用

说到互相启动 不得不提一下 Action 了。也就是 系统怎么知道你想启动的是什么。 如果之前有接触过 JavaWeb 的同学知道, 在 web.xml 中有 url-parttern , action 的作用与这相似 也就是在 intent 中设置 action,startActivity 或是 sendBroadcast 等启动时,系统查找能处理该 action 的

当然如果你知道这个 activity service 或是 Broadcast 的类名, 直接 new Intent(mContext, XXActivity.class) 也可以,只是在不同 app 之间就不能这么用了。

Intent 中的 Extra

Intent 中可以通过 putExtra 将键值对存放在 Bundle mExtra中,这个键值对 如果你忘了其 key 是多少了, 可以直接 intent.getExtra().toString(), Bundle 的 toString 的实现方式就是 map.toString() 也就是 print “key = value & …”,有时会看到 “Bundle[mParcelledData.dataSize=?]”, 此时想看对方存入的内容是什么 这个时候得提一下 unparcel

unparcel 方法的大概内容是 将mParcelledData 转成 mMap,此时就可以直接 Bundle.toString 查看了。当然 如果你看了源码, 发现它居然访问权限是 package 的,怎么调用呢? 使用反射吗? 不, 这里有一个 tricky 的方法。有一大堆的 public 方法,比如

public int size() {

unparcel();

return mMap.size();

}

我们可以写成:

bundle.size(); //有点乱入 = =

android.content.Log.d(TAG, bundle.toString());

提到 parcel, 得提一下 parcelable marshall unmarshall.

当你想把一个非基本参数类(非Boolean Integer String常见类)放入到 Bundle, 这个时候可以考虑用 parcel,也就是将你的类 implements parcelable (有点像 Serializable), 写其 writeParcel readParcel 方法。 当然,在 intent.putParcelableXX时,“可能“(待确认)需要设置额外的 classLoader, 即 在 parcel 之前, intent.setExtrasClassLoader(MyParcel.class.getClassLoader()). 此时 有一个很 buggy 的情况发生了,即

如果你使用 intent.hasExtra (其实是任何一处调用 unparcel 的方法), 会出现 XXXexception, 大概内容是 exception when unmarshall data。

其根本原因(待确认)是:如果在 parcel 之前,setExtrasClassLoader 需要在 unparcel 之前 setExtrasClassLoader。也就是 在任何一处可能收到这个 Intent 的地方需要 setExtrasClassLoader.

有点恐怖 - -,所以 慎用 parcel 或者 setExtrasClassLoader(难道这个可以作为安全选项,只有自己的应用才知道到底要 set 什么 classLoader?)

(待修复)

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐