Android中的Parcel机制,今年最新整理的《高频Android面试题集合》

  1. }

  2. return;

  3. }

  4. case BINDER_TYPE_WEAK_HANDLE: {

  5. const wp b = proc->getWeakProxyForHandle(obj.handle);

  6. if (b != NULL) b.get_refs()->decWeak(who);

  7. return;

  8. }

  9. case BINDER_TYPE_FD: {

  10. if (obj.cookie != (void*)0) close(obj.handle);

  11. return;

  12. }

  13. }

  14. LOGE(“Invalid object type 0x%08lx”, obj.type);

  15. }

  16. inline static status_t finish_flatten_binder(

  17. const sp& binder, const flat_binder_object& flat, Parcel* out)

  18. {

  19. return out->writeObject(flat, false);

  20. }

  21. status_t flatten_binder(const sp& proc,

  22. const sp& binder, Parcel* out)

  23. {

  24. flat_binder_object obj;

  25. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

  26. if (binder != NULL) {

  27. IBinder *local = binder->localBinder();

  28. if (!local) {

  29. BpBinder *proxy = binder->remoteBinder();

  30. if (proxy == NULL) {

  31. LOGE(“null proxy”);

  32. }

  33. const int32_t handle = proxy ? proxy->handle() : 0;

  34. obj.type = BINDER_TYPE_HANDLE;

  35. obj.handle = handle;

  36. obj.cookie = NULL;

  37. } else {

  38. obj.type = BINDER_TYPE_BINDER;

  39. obj.binder = local->getWeakRefs();

  40. obj.cookie = local;

  41. }

  42. } else {

  43. obj.type = BINDER_TYPE_BINDER;

  44. obj.binder = NULL;

  45. obj.cookie = NULL;

  46. }

  47. return finish_flatten_binder(binder, obj, out);

  48. }

  49. status_t flatten_binder(const sp& proc,

  50. const wp& binder, Parcel* out)

  51. {

  52. flat_binder_object obj;

  53. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

  54. if (binder != NULL) {

  55. sp real = binder.promote();

  56. if (real != NULL) {

  57. IBinder *local = real->localBinder();

  58. if (!local) {

  59. BpBinder *proxy = real->remoteBinder();

  60. if (proxy == NULL) {

  61. LOGE(“null proxy”);

  62. }

  63. const int32_t handle = proxy ? proxy->handle() : 0;

  64. obj.type = BINDER_TYPE_WEAK_HANDLE;

  65. obj.handle = handle;

  66. obj.cookie = NULL;

  67. } else {

  68. obj.type = BINDER_TYPE_WEAK_BINDER;

  69. obj.binder = binder.get_refs();

  70. obj.cookie = binder.unsafe_get();

  71. }

  72. return finish_flatten_binder(real, obj, out);

  73. }

  74. // XXX How to deal?  In order to flatten the given binder,

  75. // we need to probe it for information, which requires a primary

  76. // reference…  but we don’t have one.

  77. //

  78. // The OpenBinder implementation uses a dynamic_cast<> here,

  79. // but we can’t do that with the different reference counting

  80. // implementation we are using.

  81. LOGE(“Unable to unflatten Binder weak reference!”);

  82. obj.type = BINDER_TYPE_BINDER;

  83. obj.binder = NULL;

  84. obj.cookie = NULL;

  85. return finish_flatten_binder(NULL, obj, out);

  86. } else {

  87. obj.type = BINDER_TYPE_BINDER;

  88. obj.binder = NULL;

  89. obj.cookie = NULL;

  90. return finish_flatten_binder(NULL, obj, out);

  91. }

  92. }

  93. inline static status_t finish_unflatten_binder(

  94. BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)

  95. {

  96. return NO_ERROR;

  97. }

  98. status_t unflatten_binder(const sp& proc,

  99. const Parcel& in, sp* out)

  100. {

  101. const flat_binder_object* flat = in.readObject(false);

  102. if (flat) {

  103. switch (flat->type) {

  104. case BINDER_TYPE_BINDER:

  105. *out = static_cast<IBinder*>(flat->cookie);

  106. return finish_unflatten_binder(NULL, *flat, in);

  107. case BINDER_TYPE_HANDLE:

  108. *out = proc->getStrongProxyForHandle(flat->handle);

  109. return finish_unflatten_binder(

  110. static_cast<BpBinder*>(out->get()), *flat, in);

  111. }

  112. }

  113. return BAD_TYPE;

  114. }

  115. status_t unflatten_binder(const sp& proc,

  116. const Parcel& in, wp* out)

  117. {

  118. const flat_binder_object* flat = in.readObject(false);

  119. if (flat) {

  120. switch (flat->type) {

  121. case BINDER_TYPE_BINDER:

  122. *out = static_cast<IBinder*>(flat->cookie);

  123. return finish_unflatten_binder(NULL, *flat, in);

  124. case BINDER_TYPE_WEAK_BINDER:

  125. if (flat->binder != NULL) {

  126. out->set_object_and_refs(

  127. static_cast<IBinder*>(flat->cookie),

  128. static_castRefBase::weakref\_type\*(flat->binder));

  129. } else {

  130. *out = NULL;

  131. }

  132. return finish_unflatten_binder(NULL, *flat, in);

  133. case BINDER_TYPE_HANDLE:

  134. case BINDER_TYPE_WEAK_HANDLE:

  135. *out = proc->getWeakProxyForHandle(flat->handle);

  136. return finish_unflatten_binder(

  137. static_cast<BpBinder*>(out->unsafe_get()), *flat, in);

  138. }

  139. }

  140. return BAD_TYPE;

  141. }

  142. // ---------------------------------------------------------------------------

  143. Parcel::Parcel()

  144. {

  145. initState();

  146. }

  147. Parcel::~Parcel()

  148. {

  149. freeDataNoInit();

  150. }

  151. const uint8_t* Parcel::data() const

  152. {

  153. return mData;

  154. }

  155. size_t Parcel::dataSize() const

  156. {

  157. return (mDataSize > mDataPos ? mDataSize : mDataPos);

  158. }

  159. size_t Parcel::dataAvail() const

  160. {

  161. // TODO: decide what to do about the possibility that this can

  162. // report an available-data size that exceeds a Java int’s max

  163. // positive value, causing havoc.  Fortunately this will only

  164. // happen if someone constructs a Parcel containing more than two

  165. // gigabytes of data, which on typical phone hardware is simply

  166. // not possible.

  167. return dataSize() - dataPosition();

  168. }

  169. size_t Parcel::dataPosition() const

  170. {

  171. return mDataPos;

  172. }

  173. size_t Parcel::dataCapacity() const

  174. {

  175. return mDataCapacity;

  176. }

  177. status_t Parcel::setDataSize(size_t size)

  178. {

  179. status_t err;

  180. err = continueWrite(size);

  181. if (err == NO_ERROR) {

  182. mDataSize = size;

  183. LOGV(“setDataSize Setting data size of %p to %d/n”, this, mDataSize);

  184. }

  185. return err;

  186. }

  187. void Parcel::setDataPosition(size_t pos) const

  188. {

  189. mDataPos = pos;

  190. mNextObjectHint = 0;

  191. }

  192. status_t Parcel::setDataCapacity(size_t size)

  193. {

  194. if (size > mDataSize) return continueWrite(size);

  195. return NO_ERROR;

  196. }

  197. status_t Parcel::setData(const uint8_t* buffer, size_t len)

  198. {

  199. status_t err = restartWrite(len);

  200. if (err == NO_ERROR) {

  201. memcpy(const_cast<uint8_t*>(data()), buffer, len);

  202. mDataSize = len;

  203. mFdsKnown = false;

  204. }

  205. return err;

  206. }

  207. status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)

  208. {

  209. const sp proc(ProcessState::self());

  210. status_t err;

  211. uint8_t *data = parcel->mData;

  212. size_t *objects = parcel->mObjects;

  213. size_t size = parcel->mObjectsSize;

  214. int startPos = mDataPos;

  215. int firstIndex = -1, lastIndex = -2;

  216. if (len == 0) {

  217. return NO_ERROR;

  218. }

  219. // range checks against the source parcel size

  220. if ((offset > parcel->mDataSize)

  221. || (len > parcel->mDataSize)

  222. || (offset + len > parcel->mDataSize)) {

  223. return BAD_VALUE;

  224. }

  225. // Count objects in range

  226. for (int i = 0; i < (int) size; i++) {

  227. size_t off = objects[i];

  228. if ((off >= offset) && (off < offset + len)) {

  229. if (firstIndex == -1) {

  230. firstIndex = i;

  231. }

  232. lastIndex = i;

  233. }

  234. }

  235. int numObjects = lastIndex - firstIndex + 1;

  236. // grow data

  237. err = growData(len);

  238. if (err != NO_ERROR) {

  239. return err;

  240. }

  241. // append data

  242. memcpy(mData + mDataPos, data + offset, len);

  243. mDataPos += len;

  244. mDataSize += len;

  245. if (numObjects > 0) {

  246. // grow objects

  247. if (mObjectsCapacity < mObjectsSize + numObjects) {

  248. int newSize = ((mObjectsSize + numObjects)*3)/2;

  249. size_t *objects =

  250. (size_t*)realloc(mObjects, newSize*sizeof(size_t));

  251. if (objects == (size_t*)0) {

  252. return NO_MEMORY;

  253. }

  254. mObjects = objects;

  255. mObjectsCapacity = newSize;

  256. }

  257. // append and acquire objects

  258. int idx = mObjectsSize;

  259. for (int i = firstIndex; i <= lastIndex; i++) {

  260. size_t off = objects[i] - offset + startPos;

  261. mObjects[idx++] = off;

  262. mObjectsSize++;

  263. flat_binder_object* flat

  264. = reinterpret_cast<flat_binder_object*>(mData + off);

  265. acquire_object(proc, *flat, this);

  266. if (flat->type == BINDER_TYPE_FD) {

  267. // If this is a file descriptor, we need to dup it so the

  268. // new Parcel now owns its own fd, and can declare that we

  269. // officially know we have fds.

  270. flat->handle = dup(flat->handle);

  271. flat->cookie = (void*)1;

  272. mHasFds = mFdsKnown = true;

  273. }

  274. }

  275. }

  276. return NO_ERROR;

  277. }

  278. bool Parcel::hasFileDescriptors() const

  279. {

  280. if (!mFdsKnown) {

  281. scanForFds();

  282. }

  283. return mHasFds;

  284. }

  285. status_t Parcel::writeInterfaceToken(const String16& interface)

  286. {

  287. // currently the interface identification token is just its name as a string

  288. return writeString16(interface);

  289. }

  290. bool Parcel::checkInterface(IBinder* binder) const

  291. {

  292. return enforceInterface(binder->getInterfaceDescriptor());

  293. }

  294. bool Parcel::enforceInterface(const String16& interface) const

  295. {

  296. const String16 str(readString16());

  297. if (str == interface) {

  298. return true;

  299. } else {

  300. LOGW(“**** enforceInterface() expected ‘%s’ but read ‘%s’/n”,

  301. String8(interface).string(), String8(str).string());

  302. return false;

  303. }

  304. }

  305. const size_t* Parcel::objects() const

  306. {

  307. return mObjects;

  308. }

  309. size_t Parcel::objectsCount() const

  310. {

  311. return mObjectsSize;

  312. }

  313. status_t Parcel::errorCheck() const

  314. {

  315. return mError;

  316. }

  317. void Parcel::setError(status_t err)

  318. {

  319. mError = err;

  320. }

  321. status_t Parcel::finishWrite(size_t len)

  322. {

  323. //printf(“Finish write of %d/n”, len);

  324. mDataPos += len;

  325. LOGV(“finishWrite Setting data pos of %p to %d/n”, this, mDataPos);

  326. if (mDataPos > mDataSize) {

  327. mDataSize = mDataPos;

  328. LOGV(“finishWrite Setting data size of %p to %d/n”, this, mDataSize);

  329. }

  330. //printf(“New pos=%d, size=%d/n”, mDataPos, mDataSize);

  331. return NO_ERROR;

  332. }

  333. status_t Parcel::writeUnpadded(const void* data, size_t len)

  334. {

  335. size_t end = mDataPos + len;

  336. if (end < mDataPos) {

  337. // integer overflow

  338. return BAD_VALUE;

  339. }

  340. if (end <= mDataCapacity) {

  341. restart_write:

  342. memcpy(mData+mDataPos, data, len);

  343. return finishWrite(len);

  344. }

  345. status_t err = growData(len);

  346. if (err == NO_ERROR) goto restart_write;

  347. return err;

  348. }

  349. status_t Parcel::write(const void* data, size_t len)

  350. {

  351. void* const d = writeInplace(len);

  352. if (d) {

  353. memcpy(d, data, len);

  354. return NO_ERROR;

  355. }

  356. return mError;

  357. }

  358. void* Parcel::writeInplace(size_t len)

  359. {

  360. const size_t padded = PAD_SIZE(len);

  361. // sanity check for integer overflow

  362. if (mDataPos+padded < mDataPos) {

  363. return NULL;

  364. }

  365. if ((mDataPos+padded) <= mDataCapacity) {

  366. restart_write:

  367. //printf(“Writing %ld bytes, padded to %ld/n”, len, padded);

  368. uint8_t* const data = mData+mDataPos;

  369. // Need to pad at end?

  370. if (padded != len) {

  371. #if BYTE_ORDER == BIG_ENDIAN

  372. static const uint32_t mask[4] = {

  373. 0x00000000, 0xffffff00, 0xffff0000, 0xff000000

  374. };

  375. #endif

  376. #if BYTE_ORDER == LITTLE_ENDIAN

  377. static const uint32_t mask[4] = {

  378. 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff

  379. };

  380. #endif

  381. //printf(“Applying pad mask: %p to %p/n”, (void*)mask[padded-len],

  382. //    *reinterpret_cast<void**>(data+padded-4));

  383. *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];

  384. }

  385. finishWrite(padded);

  386. return data;

  387. }

  388. status_t err = growData(padded);

  389. if (err == NO_ERROR) goto restart_write;

  390. return NULL;

  391. }

  392. status_t Parcel::writeInt32(int32_t val)

  393. {

  394. return writeAligned(val);

  395. }

  396. status_t Parcel::writeInt64(int64_t val)

  397. {

  398. return writeAligned(val);

  399. }

  400. status_t Parcel::writeFloat(float val)

  401. {

  402. return writeAligned(val);

  403. }

  404. status_t Parcel::writeDouble(double val)

  405. {

  406. return writeAligned(val);

  407. }

  408. status_t Parcel::writeIntPtr(intptr_t val)

  409. {

  410. return writeAligned(val);

  411. }

  412. status_t Parcel::writeCString(const char* str)

  413. {

  414. return write(str, strlen(str)+1);

  415. }

  416. status_t Parcel::writeString8(const String8& str)

  417. {

  418. status_t err = writeInt32(str.bytes());

  419. if (err == NO_ERROR) {

  420. err = write(str.string(), str.bytes()+1);

  421. }

  422. return err;

  423. }

  424. status_t Parcel::writeString16(const String16& str)

  425. {

  426. return writeString16(str.string(), str.size());

  427. }

  428. status_t Parcel::writeString16(const char16_t* str, size_t len)

  429. {

  430. if (str == NULL) return writeInt32(-1);

  431. status_t err = writeInt32(len);

  432. if (err == NO_ERROR) {

  433. len *= sizeof(char16_t);

  434. uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));

  435. if (data) {

  436. memcpy(data, str, len);

  437. *reinterpret_cast<char16_t*>(data+len) = 0;

  438. return NO_ERROR;

  439. }

  440. err = mError;

  441. }

  442. return err;

  443. }

  444. status_t Parcel::writeStrongBinder(const sp& val)

  445. {

  446. return flatten_binder(ProcessState::self(), val, this);

  447. }

  448. status_t Parcel::writeWeakBinder(const wp& val)

  449. {

  450. return flatten_binder(ProcessState::self(), val, this);

  451. }

  452. status_t Parcel::writeNativeHandle(const native_handle* handle)

  453. {

  454. if (!handle || handle->version != sizeof(native_handle))

  455. return BAD_TYPE;

  456. status_t err;

  457. err = writeInt32(handle->numFds);

  458. if (err != NO_ERROR) return err;

  459. err = writeInt32(handle->numInts);

  460. if (err != NO_ERROR) return err;

  461. for (int i=0 ; err==NO_ERROR && inumFds ; i++)

  462. err = writeDupFileDescriptor(handle->data[i]);

  463. if (err != NO_ERROR) {

  464. LOGD(“write native handle, write dup fd failed”);

  465. return err;

  466. }

  467. err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);

  468. return err;

  469. }

  470. status_t Parcel::writeFileDescriptor(int fd)

  471. {

  472. flat_binder_object obj;

  473. obj.type = BINDER_TYPE_FD;

  474. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

  475. obj.handle = fd;

  476. obj.cookie = (void*)0;

  477. return writeObject(obj, true);

  478. }

  479. status_t Parcel::writeDupFileDescriptor(int fd)

  480. {

  481. flat_binder_object obj;

  482. obj.type = BINDER_TYPE_FD;

  483. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

  484. obj.handle = dup(fd);

  485. obj.cookie = (void*)1;

  486. return writeObject(obj, true);

  487. }

  488. status_t Parcel::write(const Flattenable& val)

  489. {

  490. status_t err;

  491. // size if needed

  492. size_t len = val.getFlattenedSize();

  493. size_t fd_count = val.getFdCount();

  494. err = this->writeInt32(len);

  495. if (err) return err;

  496. err = this->writeInt32(fd_count);

  497. if (err) return err;

  498. // payload

  499. void* buf = this->writeInplace(PAD_SIZE(len));

  500. if (buf == NULL)

  501. return BAD_VALUE;

  502. int* fds = NULL;

  503. if (fd_count) {

  504. fds = new int[fd_count];

  505. }

  506. err = val.flatten(buf, len, fds, fd_count);

  507. for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {

  508. err = this->writeDupFileDescriptor( fds[i] );

  509. }

  510. if (fd_count) {

  511. delete [] fds;

  512. }

  513. return err;

  514. }

  515. status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)

  516. {

  517. const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;

  518. const bool enoughObjects = mObjectsSize < mObjectsCapacity;

  519. if (enoughData && enoughObjects) {

  520. restart_write:

  521. *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;

  522. // Need to write meta-data?

  523. if (nullMetaData || val.binder != NULL) {

  524. mObjects[mObjectsSize] = mDataPos;

  525. acquire_object(ProcessState::self(), val, this);

  526. mObjectsSize++;

  527. }

  528. // remember if it’s a file descriptor

  529. if (val.type == BINDER_TYPE_FD) {

  530. mHasFds = mFdsKnown = true;

  531. }

  532. return finishWrite(sizeof(flat_binder_object));

  533. }

  534. if (!enoughData) {

  535. const status_t err = growData(sizeof(val));

  536. if (err != NO_ERROR) return err;

  537. }

  538. if (!enoughObjects) {

  539. size_t newSize = ((mObjectsSize+2)*3)/2;

  540. size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));

  541. if (objects == NULL) return NO_MEMORY;

  542. mObjects = objects;

  543. mObjectsCapacity = newSize;

  544. }

  545. goto restart_write;

  546. }

  547. void Parcel::remove(size_t start, size_t amt)

  548. {

  549. LOG_ALWAYS_FATAL(“Parcel::remove() not yet implemented!”);

  550. }

  551. status_t Parcel::read(void* outData, size_t len) const

  552. {

  553. if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {

  554. memcpy(outData, mData+mDataPos, len);

  555. mDataPos += PAD_SIZE(len);

  556. LOGV(“read Setting data pos of %p to %d/n”, this, mDataPos);

  557. return NO_ERROR;

  558. }

  559. return NOT_ENOUGH_DATA;

  560. }

  561. const void* Parcel::readInplace(size_t len) const

  562. {

  563. if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {

  564. const void* data = mData+mDataPos;

  565. mDataPos += PAD_SIZE(len);

  566. LOGV(“readInplace Setting data pos of %p to %d/n”, this, mDataPos);

  567. return data;

  568. }

  569. return NULL;

  570. }

  571. template

  572. status_t Parcel::readAligned(T *pArg) const {

  573. COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));

  574. if ((mDataPos+sizeof(T)) <= mDataSize) {

  575. const void* data = mData+mDataPos;

  576. mDataPos += sizeof(T);

  577. *pArg =  *reinterpret_cast<const T*>(data);

  578. return NO_ERROR;

  579. } else {

  580. return NOT_ENOUGH_DATA;

  581. }

  582. }

  583. template

  584. T Parcel::readAligned() const {

  585. T result;

  586. if (readAligned(&result) != NO_ERROR) {

  587. result = 0;

  588. }

  589. return result;

  590. }

  591. template

  592. status_t Parcel::writeAligned(T val) {

  593. COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));

  594. if ((mDataPos+sizeof(val)) <= mDataCapacity) {

  595. restart_write:

  596. *reinterpret_cast<T*>(mData+mDataPos) = val;

  597. return finishWrite(sizeof(val));

  598. }

  599. status_t err = growData(sizeof(val));

  600. if (err == NO_ERROR) goto restart_write;

  601. return err;

  602. }

  603. status_t Parcel::readInt32(int32_t *pArg) const

  604. {

  605. return readAligned(pArg);

  606. }

  607. int32_t Parcel::readInt32() const

  608. {

  609. return readAligned<int32_t>();

  610. }

  611. status_t Parcel::readInt64(int64_t *pArg) const

  612. {

  613. return readAligned(pArg);

  614. }

  615. int64_t Parcel::readInt64() const

  616. {

  617. return readAligned<int64_t>();

  618. }

  619. status_t Parcel::readFloat(float *pArg) const

  620. {

  621. return readAligned(pArg);

  622. }

  623. float Parcel::readFloat() const

  624. {

  625. return readAligned<float>();

  626. }

  627. status_t Parcel::readDouble(double *pArg) const

  628. {

  629. return readAligned(pArg);

  630. }

  631. double Parcel::readDouble() const

  632. {

  633. return readAligned<double>();

  634. }

  635. status_t Parcel::readIntPtr(intptr_t *pArg) const

  636. {

  637. return readAligned(pArg);

  638. }

  639. intptr_t Parcel::readIntPtr() const

  640. {

  641. return readAligned<intptr_t>();

  642. }

  643. const char* Parcel::readCString() const

  644. {

  645. const size_t avail = mDataSize-mDataPos;

  646. if (avail > 0) {

  647. const char* str = reinterpret_cast<const char*>(mData+mDataPos);

  648. // is the string’s trailing NUL within the parcel’s valid bounds?

  649. const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));

  650. if (eos) {

  651. const size_t len = eos - str;

  652. mDataPos += PAD_SIZE(len+1);

  653. LOGV(“readCString Setting data pos of %p to %d/n”, this, mDataPos);

  654. return str;

  655. }

  656. }

  657. return NULL;

  658. }

  659. String8 Parcel::readString8() const

  660. {

  661. int32_t size = readInt32();

  662. // watch for potential int overflow adding 1 for trailing NUL

  663. if (size > 0 && size < INT32_MAX) {

  664. const char* str = (const char*)readInplace(size+1);

  665. if (str) return String8(str, size);

  666. }

  667. return String8();

  668. }

  669. String16 Parcel::readString16() const

  670. {

  671. size_t len;

  672. const char16_t* str = readString16Inplace(&len);

  673. if (str) return String16(str, len);

  674. LOGE(“Reading a NULL string not supported here.”);

  675. return String16();

  676. }

  677. const char16_t* Parcel::readString16Inplace(size_t* outLen) const

  678. {

  679. int32_t size = readInt32();

  680. // watch for potential int overflow from size+1

  681. if (size >= 0 && size < INT32_MAX) {

  682. *outLen = size;

  683. const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));

  684. if (str != NULL) {

  685. return str;

  686. }

  687. }

  688. *outLen = 0;

  689. return NULL;

  690. }

  691. sp Parcel::readStrongBinder() const

  692. {

  693. sp val;

  694. unflatten_binder(ProcessState::self(), *this, &val);

  695. return val;

  696. }

  697. wp Parcel::readWeakBinder() const

  698. {

  699. wp val;

  700. unflatten_binder(ProcessState::self(), *this, &val);

  701. return val;

  702. }

  703. native_handle* Parcel::readNativeHandle() const

  704. {

  705. int numFds, numInts;

  706. status_t err;

  707. err = readInt32(&numFds);

  708. if (err != NO_ERROR) return 0;

  709. err = readInt32(&numInts);

  710. if (err != NO_ERROR) return 0;

  711. native_handle* h = native_handle_create(numFds, numInts);

  712. for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {

  713. h->data[i] = dup(readFileDescriptor());

  714. if (h->data[i] < 0) err = BAD_VALUE;

  715. }

  716. err = read(h->data + numFds, sizeof(int)*numInts);

  717. if (err != NO_ERROR) {

  718. native_handle_close(h);

  719. native_handle_delete(h);

  720. h = 0;

  721. }

  722. return h;

  723. }

  724. int Parcel::readFileDescriptor() const

  725. {

  726. const flat_binder_object* flat = readObject(true);

  727. if (flat) {

  728. switch (flat->type) {

  729. case BINDER_TYPE_FD:

  730. //LOGI(“Returning file descriptor %ld from parcel %p/n”, flat->handle, this);

  731. return flat->handle;

  732. }

  733. }

  734. return BAD_TYPE;

  735. }

  736. status_t Parcel::read(Flattenable& val) const

  737. {

  738. // size

  739. const size_t len = this->readInt32();

  740. const size_t fd_count = this->readInt32();

  741. // payload

  742. void const* buf = this->readInplace(PAD_SIZE(len));

  743. if (buf == NULL)

  744. return BAD_VALUE;

  745. int* fds = NULL;

  746. if (fd_count) {

  747. fds = new int[fd_count];

  748. }

  749. status_t err = NO_ERROR;

  750. for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {

  751. fds[i] = dup(this->readFileDescriptor());

  752. if (fds[i] < 0) err = BAD_VALUE;

  753. }

  754. if (err == NO_ERROR) {

  755. err = val.unflatten(buf, len, fds, fd_count);

  756. }

  757. if (fd_count) {

  758. delete [] fds;

  759. }

  760. return err;

  761. }

  762. const flat_binder_object* Parcel::readObject(bool nullMetaData) const

  763. {

  764. const size_t DPOS = mDataPos;

  765. if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {

  766. const flat_binder_object* obj

  767. = reinterpret_cast<const flat_binder_object*>(mData+DPOS);

  768. mDataPos = DPOS + sizeof(flat_binder_object);

  769. if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {

  770. // When transferring a NULL object, we don’t write it into

  771. // the object list, so we don’t want to check for it when

  772. // reading.

  773. LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);

  774. return obj;

  775. }

  776. // Ensure that this object is valid…

  777. size_t* const OBJS = mObjects;

  778. const size_t N = mObjectsSize;

  779. size_t opos = mNextObjectHint;

  780. if (N > 0) {

  781. LOGV(“Parcel %p looking for obj at %d, hint=%d/n”,

  782. this, DPOS, opos);

  783. // Start at the current hint position, looking for an object at

  784. // the current data position.

  785. if (opos < N) {

  786. while (opos < (N-1) && OBJS[opos] < DPOS) {

  787. opos++;

  788. }

  789. } else {

  790. opos = N-1;

  791. }

  792. if (OBJS[opos] == DPOS) {

  793. // Found it!

  794. LOGV(“Parcel found obj %d at index %d with forward search”,

  795. this, DPOS, opos);

  796. mNextObjectHint = opos+1;

  797. LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);

  798. return obj;

  799. }

  800. // Look backwards for it…

  801. while (opos > 0 && OBJS[opos] > DPOS) {

  802. opos–;

  803. }

  804. if (OBJS[opos] == DPOS) {

  805. // Found it!

  806. LOGV(“Parcel found obj %d at index %d with backward search”,

  807. this, DPOS, opos);

  808. mNextObjectHint = opos+1;

  809. LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);

  810. return obj;

  811. }

  812. }

  813. LOGW(“Attempt to read object from Parcel %p at offset %d that is not in the object list”,

  814. this, DPOS);

  815. }

  816. return NULL;

  817. }

  818. void Parcel::closeFileDescriptors()

  819. {

  820. size_t i = mObjectsSize;

  821. if (i > 0) {

  822. //LOGI(“Closing file descriptors for %d objects…”, mObjectsSize);

  823. }

  824. while (i > 0) {

  825. i–;

  826. const flat_binder_object* flat

  827. = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);

  828. if (flat->type == BINDER_TYPE_FD) {

  829. //LOGI(“Closing fd: %ld/n”, flat->handle);

  830. close(flat->handle);

  831. }

  832. }

  833. }

  834. const uint8_t* Parcel::ipcData() const

  835. {

  836. return mData;

  837. }

  838. size_t Parcel::ipcDataSize() const

  839. {

  840. return (mDataSize > mDataPos ? mDataSize : mDataPos);

  841. }

  842. const size_t* Parcel::ipcObjects() const

  843. {

  844. return mObjects;

  845. }

  846. size_t Parcel::ipcObjectsCount() const

  847. {

  848. return mObjectsSize;

  849. }

  850. void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,

  851. const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)

  852. {

  853. freeDataNoInit();

  854. mError = NO_ERROR;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

尾声

评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。

有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。

一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。

at->handle);

  1. }

  2. }

  3. }

  4. const uint8_t* Parcel::ipcData() const

  5. {

  6. return mData;

  7. }

  8. size_t Parcel::ipcDataSize() const

  9. {

  10. return (mDataSize > mDataPos ? mDataSize : mDataPos);

  11. }

  12. const size_t* Parcel::ipcObjects() const

  13. {

  14. return mObjects;

  15. }

  16. size_t Parcel::ipcObjectsCount() const

  17. {

  18. return mObjectsSize;

  19. }

  20. void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,

  21. const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)

  22. {

  23. freeDataNoInit();

  24. mError = NO_ERROR;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-KLUrssCT-1710507451184)]
[外链图片转存中…(img-95ypRGhr-1710507451185)]
[外链图片转存中…(img-K1NsV9CS-1710507451185)]
[外链图片转存中…(img-zDBe2wTr-1710507451186)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-jE3ne6Gt-1710507451186)]

尾声

评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。

有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。

一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。

由于文章篇幅问题复制链接查看详细文章以及获取学习笔记链接:前往我的GitHub

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值