Android跨進(jìn)程傳遞大數(shù)據(jù)的方法實(shí)現(xiàn)
最近要從Service端給Client端傳遞圖片數(shù)據(jù),之前的數(shù)據(jù)都是通過aidl傳遞:
創(chuàng)建 Parcelable文件
ImageData.java
public class ImageData implements Parcelable { private byte[] data; public byte[] getData() { return data; } public ImageData(byte[] dataIn) { this.data = dataIn; } public ImageData(Parcel in) { int arrayLength = in.readInt(); if (arrayLength > 0) { data = new byte[arrayLength]; in.readByteArray(data); } } @Override public void writeToParcel(Parcel dest, int flags) { if (data != null && data.length > 0) { dest.writeInt(data.length); dest.writeByteArray(data); } else { dest.writeInt(0); } } ... } test.aidl interface test { void sendMessage(ImageData data); }
運(yùn)行報(bào)錯(cuò):
android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(BinderProxy.java:514)
...
原因
這里導(dǎo)致DeadObjectException的原因主要是binder創(chuàng)建的buffer被占滿了:
kernel/msm-4.4/drivers/android/binder_alloc.c
315 if (best_fit == NULL) {
...
341 pr_err("%d: binder_alloc_buf size %zd failed, no address space\n",
342 alloc->pid, size);
343 pr_err("allocated: %zd (num: %zd largest: %zd), free: %zd (num: %zd largest: %zd)\n",
344 total_alloc_size, allocated_buffers, largest_alloc_size,
345 total_free_size, free_buffers, largest_free_size);
346 eret = ERR_PTR(-ENOSPC);
347 goto error_unlock;
348 }
傳輸中如果數(shù)據(jù)大于free_buffers,則會(huì)拋出DeadObjectException
解決
1.socket
socke傳輸不受大小限制,但實(shí)現(xiàn)比較復(fù)雜
2.文件
通過文件傳輸比較簡(jiǎn)單,但效率差,而且高版本會(huì)受到Android系統(tǒng)權(quán)限限制
3.數(shù)據(jù)切割
將較大數(shù)據(jù)切割成較小的數(shù)據(jù)傳輸,此方法是兼顧效率,復(fù)雜度較好的方案
定義數(shù)據(jù)體:
public class SliceData implements Parcelable { private byte[] data; private int length; ... }
切割數(shù)據(jù)方法:
public static byte[][] divideArray(byte[] source, int chunkSize) { int totalLength = source.length; int arraySize = (int) Math.ceil(totalLength / (double) chunkSize); byte[][] ret = new byte[arraySize][chunkSize]; int start = 0; int parts = 0; for (int i = 0; i < arraySize; i++) { if (start + chunkSize > totalLength) { System.arraycopy(source, start, ret[i], 0, source.length - start); } else { System.arraycopy(source, start, ret[i], 0, chunkSize); } start += chunkSize; parts++; } return ret; }
將SliceData按順序構(gòu)建發(fā)送:
byte[][] divideData = divideArray(testBytes, 64 * 1024);//64k for (byte[] item : divideData) { mEmitter.onNext(new SliceData(length, item)); }
client接收:
int chunkSize = bytes.length; if(buffer == null) { buffer = new byte[length]; index = 0; } if (index + chunkSize > bodyLength) {//最后一個(gè)數(shù)據(jù)塊 System.arraycopy(bytes, 0, buffer, index, bodyLength - index); visualResultData.bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length); buffer = null; index = 0; } else { System.arraycopy(bytes, 0, buffer, index, chunkSize); index += chunkSize; }
4.第三方
binder本身也是利用mmap,可以利用實(shí)現(xiàn)mmap的框架,比如 MMKV
5.Bitmap
如果傳輸?shù)臄?shù)據(jù)是Bitmap,還可以用Bundle的putBinder方案
定義binder:
class ImageBinder extends IRemoteGetBitmap.Stub { @Override public Bitmap getBitMap() throws RemoteException { return mBitmap; } }
發(fā)送
Bundle bundle = new Bundle(); bundle.putBinder("bitmap", new ImageBinder()); intent.putExtras(bundle);
接收:
ImageBinder imageBinder = (ImageBinder) bundle.getBinder("bitmap"); Bitmap bitmap = imageBinder.getBitmap();
到此這篇關(guān)于Android跨進(jìn)程傳遞大數(shù)據(jù)的方法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Android跨進(jìn)程傳遞大數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android編程實(shí)現(xiàn)ActionBar的home圖標(biāo)動(dòng)畫切換效果
這篇文章主要介紹了Android編程實(shí)現(xiàn)ActionBar的home圖標(biāo)動(dòng)畫切換效果,涉及Android布局、樣式、Activity及菜單相關(guān)操作技巧,需要的朋友可以參考下2017-01-01C/C++在Java、Android和Objective-C三大平臺(tái)下實(shí)現(xiàn)混合編程
本文主要介紹C/C++在Java、Android和Objective-C三大平臺(tái)下實(shí)現(xiàn)混合編程,這里舉例說明實(shí)現(xiàn)不同平臺(tái)用C/C++實(shí)現(xiàn)編程的方法,有興趣的小伙伴可以參考下2016-08-08Android數(shù)據(jù)庫增刪改查實(shí)戰(zhàn)案例
我們?cè)诰幊讨薪?jīng)常會(huì)遇到數(shù)據(jù)庫的操作,這篇文章主要給大家介紹了關(guān)于Android數(shù)據(jù)庫增刪改查的相關(guān)資料,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04接口對(duì)象的實(shí)例化在接口回調(diào)中的使用方法
下面小編就為大家?guī)硪黄涌趯?duì)象的實(shí)例化在接口回調(diào)中的使用方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02Android實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12photoView實(shí)現(xiàn)圖片多點(diǎn)觸控效果
這篇文章主要為大家詳細(xì)介紹了photoView實(shí)現(xiàn)圖片多點(diǎn)觸控效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android應(yīng)用啟動(dòng)速度優(yōu)化
這篇文章主要介紹了Android應(yīng)用啟動(dòng)速度優(yōu)化的相關(guān)資料,需要的朋友可以參考下2016-01-01Android實(shí)現(xiàn)新增及編輯聯(lián)系人的方法
這篇文章主要介紹了Android實(shí)現(xiàn)新增及編輯聯(lián)系人的方法,是Android應(yīng)用開發(fā)常見的功能,需要的朋友可以參考下2014-07-07Android ToggleButton 詳解及實(shí)例代碼
這篇文章主要介紹了Android ToggleButton 詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02