8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
在 Android 四大组件中 Activity、Service、Receiver 都支持在 Intent 中附加传递 Bundle 数据。
Bundle 是以键值对的形式存储数据,支持基本数据类型、数组、实现 Serializable 或 Parcelable 接口的对象以及一些 Android 支持的特殊对象。// 发送数据
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("userName", "wshunli");
intent.putExtras(bundle);
startActivity(intent);
// 接收数据
Bundle bundle = getIntent().getExtras();
String userName = null;
if (bundle != null) {
userName = bundle.getString("userName");
}
Log.d(TAG, "userName: " + userName);
使用 Bundle 的 put 与 get 方法族将数据保存至 bundle 对象,调用 Intent 的 putExtras 方法即可。
Bundle 源码分析,Bundle 继承自 BaseBundle 并实现了 Cloneable 和 Parcelable 接口。
以 Boolean 类型数据存取为例:ArrayMap mMap = null;
public void putBoolean(@Nullable String key, boolean value) {
unparcel();
mMap.put(key, value);
}
public boolean getBoolean(String key, boolean defaultValue) {
unparcel();
Object o = mMap.get(key);
if (o == null) {
return defaultValue;
}
try {
return (Boolean) o;
} catch (ClassCastException e) {
typeWarning(key, o, "Boolean", defaultValue, e);
return defaultValue;
}
}
根据源码可知数据存取都是在 ArrayMap 对象中。
其中 unparcel() 方法源码如下:/*
* If mParcelledData is non-null, then mMap will be null and the
* data are stored as a Parcel containing a Bundle. When the data
* are unparcelled, mParcelledData willbe set to null.
*/
Parcel mParcelledData = null;
/* package */ void unparcel() {
synchronized (this) {
final Parcel source = mParcelledData;
if (source != null) {
initializeFromParcelLocked(source, /*recycleParcel=*/ true);
} else {
if (DEBUG) {
Log.d(TAG, "unparcel "
+ Integer.toHexString(System.identityHashCode(this))
+ ": no parcelled data");
}
}
}
}
private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel) {
if (LOG_DEFUSABLE && sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) {
Slog.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may "
+ "clobber all data inside!", new Throwable());
}
if (isEmptyParcel(parcelledData)) {
if (DEBUG) {
Log.d(TAG, "unparcel "
+ Integer.toHexString(System.identityHashCode(this)) + ": empty");
}
if (mMap == null) {
mMap = new ArrayMap<>(1);
} else {
mMap.erase();
}
mParcelledData = null;
return;
}
final int count = parcelledData.readInt();
if (DEBUG) {
Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ ": reading " + count + " maps");
}
if (count < 0) {
return;
}
ArrayMap map = mMap;
if (map == null) {
map = new ArrayMap<>(count);
} else {
map.erase();
map.ensureCapacity(count);
}
try {
parcelledData.readArrayMapInternal(map, count, mClassLoader);
} catch (BadParcelableException e) {
if (sShouldDefuse) {
Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
map.erase();
} else {
throw e;
}
} finally {
mMap = map;
if (recycleParcel) {
recycleParcel(parcelledData);
}
mParcelledData = null;
}
if (DEBUG) {
Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ " final map: " + mMap);
}
}
只有使用 Bundle 构造函数实例化 Bundle 对象时,才会给 mParcelledData 赋值,其他大部分情况下 mParcelledData 都是 null 。BaseBundle(Parcel parcelledData) {
readFromParcelInner(parcelledData);
}
void readFromParcelInner(Parcel parcel) {
// Keep implementation in sync with readFromParcel() in
// frameworks/native/libs/binder/PersistableBundle.cpp.
int length = parcel.readInt();
readFromParcelInner(parcel, length);
}
private void readFromParcelInner(Parcel parcel, int length) {
if (length < 0) {
throw new RuntimeException("Bad length in parcel: " + length);
} else if (length == 0) {
// Empty Bundle or end of data.
mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
return;
}
final int magic = parcel.readInt();
if (magic != BUNDLE_MAGIC) {
throw new IllegalStateException("Bad magic number for Bundle: 0x"
+ Integer.toHexString(magic));
}
if (parcel.hasReadWriteHelper()) {
// If the parcel has a read-write helper, then we can't lazily-unparcel it, so just
// unparcel right away.
synchronized (this) {
initializeFromParcelLocked(parcel, /*recycleParcel=*/ false);
}
return;
}
// Advance within this Parcel
int offset = parcel.dataPosition();
parcel.setDataPosition(MathUtils.addOrThrow(offset, length));
Parcel p = Parcel.obtain();
p.setDataPosition(0);
p.appendFrom(parcel, offset, length);
p.adoptClassCookies(parcel);
if (DEBUG) Log.d(TAG, "Retrieving " + Integer.toHexString(System.identityHashCode(this))
+ ": " + length + " bundle bytes starting at " + offset);
p.setDataPosition(0);
mParcelledData = p;
}
从上述代码片段可以知道 mParcelledData 的取值有3种情况:mParcelledData = null
mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL
mParcelledData = Parcel.obtain()
在 unparcel() 方法中分别对这三种情况进行了处理,如果为 null 不进行任何操作返回;如果为 EMPTY_PARCEL 则使用 mMap = new ArrayMap<>(1) 创建长度为 1 的 ArrayMap 对象;如果为 Parcel.obtain() 则实例化 ArrayMap 对象并存储数据。如果本文对您有所帮助,且您手头还很宽裕,欢迎打赏赞助我,以支付网站服务器和域名费用。
您的鼓励与支持是我更新的最大动力,我会铭记于心,倾于博客。
本文链接:https://www.wshunli.com/posts/f0f2eaec.html