編輯:關於Android編程
public class Gril implements Parcelable {
private int mAge; // 年齡
private boolean mSexy; // 是否性感
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mAge);
dest.writeByte((byte) (mSexy ? 1 : 0));
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Gril createFromParcel(Parcel in) {
Gril gril = new Gril();
gril.mAge = in.readInt();
gril.mSexy = in.readByte() != 0;
return gril;
}
public Gril[] newArray(int size) {
return new Gril[size];
}
};
@Override
public int describeContents() {
return 0;
}
}
從上面的例子中可以看出,具體的寫入(dest.writeInt(mAge);)與讀取(gril.mAge = in.readInt();)都是針對Parcel對象進行的操作,下面貼出的是Parcle 讀寫int類型數據的定義。
public final class Parcel {
......
/**
* Write an integer value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
public final native void writeInt(int val);
/**
* Read an integer value from the parcel at the current dataPosition().
*/
public final native int readInt();
......
}
從上面代碼可以看出都是native方法說明都是使用JNI,其具體位置在system/frameworks/base/core/jni/android_util_Binder.cpp ,以下也僅以int類型讀寫為例
static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
const status_t err = parcel->writeInt32(val);
if (err != NO_ERROR) {
jniThrowException(env, java/lang/OutOfMemoryError, NULL);
}
}
}
static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
return parcel->readInt32();
}
return 0;
}
status_t Parcel::writeInt32(int32_t val)
{
return writeAligned(val);
}
template
status_t Parcel::writeAligned(T val) {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
*reinterpret_cast(mData+mDataPos) = val;
return finishWrite(sizeof(val));
}
status_t err = growData(sizeof(val));
if (err == NO_ERROR) goto restart_write;
return err;
}
status_t Parcel::readInt32(int32_t *pArg) const
{
return readAligned(pArg);
}
template
status_t Parcel::readAligned(T *pArg) const {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
if ((mDataPos+sizeof(T)) <= mDataSize) {
const void* data = mData+mDataPos;
mDataPos += sizeof(T);
*pArg = *reinterpret_cast(data);
return NO_ERROR;
} else {
return NOT_ENOUGH_DATA;
}
}
4. 對於普通數據,使用的是mData內存地址,對於IBinder類型的數據以及FileDescriptor使用的是mObjects內存地址。後者是通過flatten_binder()和unflatten_binder()實現的,目的是反序列化時讀出的對象就是原對象而不用重新new一個新對象。
dest.writeParcelableArray(mClassNameList.toArray(new ClassName[mClassNameList.size()]), flags); Parcelable[] parcelableArr = in.readParcelableArray(ClassName.class.getClassLoader()); ArrayListarrayList = new ArrayList (); for (Parcelable object : parcelableArr) { arrayList.add((ClassName)object); }
跟我學Android之十三 SQLite數據庫操作
本章內容 第1節 SQLite數據庫概述 第2節 SQLite建庫建表 第3節管理數據庫連接 第4節 操作數據庫數據 第5節 數據綁定本章目標 掌握SQLite數據的基本
Android4.4系統浏覽器Chromium實現的加載模塊與流程
本文只描述Http網絡請求相關的信息,Https、Spdy、file、ftp、websocket等的類型只提及在哪裡出現關系分支。 代碼層次圖如下: +-
Android自定義控件之仿美團下拉刷新
美團的下拉刷新分為三個狀態:第一個狀態為下拉刷新狀態(pull to refresh),在這個狀態下是一個綠色的橢圓隨著下拉的距離動態改變其大小。第二個部分為放開刷新狀態
Android DrawerLayout帶有側滑功能的布局類(2)
ActionBarDrawerToggle:在前一張中我們並沒有使用drawLayout.setDrawerListener(); 對應的參數對象就是Drawe