① android 文件流的方式多張圖片上傳,並多個參數
android 開發中圖片上傳是很正常的,有兩種可用的方式:
下面我們就說明一下以文件流上傳圖片的方式, 實現網路框架是Retrofit
測試上傳3張手機sd卡中的圖片,並傳人了參數EquipmentCode, Description, ReportUserCode等
其中的思路是: Post的方式,Content-Type:multipart/form-data的類型進行上傳文件的。
其中MultipartBody是RequestBody的擴展,
看看請求頭的信息, 請求中攜帶了所有信(如果介面開發人員說不能收到, 叫他自己想想,截圖給他,哈哈哈:)
上面的是上傳了3張圖片,如果一張,只要傳一個就行!
就這樣,圖片上傳的兩種方式ok拉,測試通過的,保證正確!
參考: https://www.jianshu.com/p/acfefb0a204f
② android oom是什麼意思
Android oom 有時出現很頻繁,這一般不是Android設計的問題,一般是我們的問題。
就我的經驗而言,出現oom,無非主要是以下幾個方面:
一、載入對象過大
二、相應資源過多,沒有來不及釋放。
解決這樣的問題,也有一下幾個方面:
一:在內存引用上做些處理,常用的有軟引用、強化引用、弱引用
二:在內存中載入圖片時直接在內存中做處理,如:邊界壓縮.
三:動態回收內存
四:優化Dalvik虛擬機的堆內存分配
五:自定義堆內存大小
③ android開發三大框架
XUtil框架、volley、ImageLoader框架。
1、XUtil框架:
主要有四大模塊:
(1) 資料庫模塊:Android中的orm框架,一行代碼就可以進行增刪改查;支持事務,默認關閉;可通過註解自定義表名,列名,外鍵,唯一性約束,NOT NULL約束,CHECK約束等(需要混淆的時候請註解表名和列名);支持綁定外鍵,保存實體時外鍵關聯實體自動保存或更新;自動載入外鍵關聯實體,支持延時載入;支持鏈式表達查詢,更直觀的查詢語義,參考下面的介紹或sample中的例子。
(2)註解模塊:android中的ioc框架,完全註解方式就可以進行UI,資源和事件綁定;新的事件綁定方式,使用混淆工具混淆後仍可正常工作;目前支持常用的20種事件綁定,參見ViewCommonEventListener類和包com.lidroid.xutils.view.annotation.event。
(3)網路模塊:支持同步,非同步方式的請正拿求;支持大文件上傳,上傳大文件不會oom;支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT請求;下載支持301/302重定向,支持設置是否根據Content-Disposition重命名下載的文件;返迴文本內容的請求(默認只啟用了GET請求)支持緩存,可設置默認過期時間和針對當前請求的過期時間。
(4)圖片緩存模塊:載入bitmap的時候無需考慮bitmap載入過程中出現的oom和android容器快速滑動時候出現的圖片錯位等現象;支持載入網路圖片和本地圖片;內存管理使用lru演算法,更好的管理bitmap內存;可配置線程載入線程數量,緩存大小,緩存路徑,載入顯示動畫等…
2、volley:JSON,圖像等的非同步下載;網路請求的排序(scheling)網路請求的優先順序處理緩存多級別取消請求和Activity和生命周期的聯動(Activity結束時同時取消所有網路請求)。
3、ImageLoader框架:支持多線程圖片載入液寬。提供豐富的細節配置,比如線程池大小,鬧清亮HTPP請求項,內存和磁碟緩存,圖片顯示時的參數配置等等;提供雙緩存,支持載入過程的監聽;提供圖片的個性化顯示配置介面。
④ android何時會發生oom怎麼解決oom
首先,OOM就是內存溢出,即Out Of Memory。也就是說內存佔有量超過了VM所分配的最大。
怎麼解決OOM,通常OOM都發生在需要用到大量內存的情況下(創建或解析Bitmap,分配特大的數組等),在這樣的一種情況下,就可能出現OOM,據我現在了解到,多數OOM都是因為Bitmap太大。所以,這里我就專門針對如何解決Bitmap的OOM。其實最核發的就是只載入可見范圍內的Bitmap,試想這樣一種情況,在GridView或ListView中,數據量有5000,每一屏只顯示20個元素,那麼不可見的,我們是不需要保存Bitmap在內在中的。所以我們就是只把那麼可見的Bitmap保留在內存中,那些不可見的,就釋放掉。當元素滑出來時,再去載入Bitmap。
這里我有兩種方式,都可以避免OOM。
⑤ android圖片壓縮避免OOM
簡單吹下牛:很多app都會要載入圖片,但是如果不壓縮圖片就很容易OOM,
個人看來OOM 出現原因總的來說分為兩種:
一種是內存溢出(好像在扯淡,OOM本身就是內存溢出)
另一種是:圖片過大,一個屏幕顯示不完全造成,似乎也是一。。 如有錯誤純屬扯淡;
為了避免上面的情況:載入圖片的時候可以進行壓縮,上傳的時候要可以進行壓縮,在圖片不可見的時候進行回收(onDetach()),再吹一句 用了fresco+壓縮之後載入圖片完全沒問題了。
一、質量壓縮方法:
privateBitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos =newByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,100, baos);//質量壓縮方法,這里100表示不壓縮,把壓縮後的數據存放到baos中
intoptions =100;
while( baos.toByteArray().length /1024>100) {//循環判斷如果壓縮後圖片是否大於100kb,大於繼續壓縮
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//這里壓縮options%,把壓縮後的數據存放到baos中
options -=10;//每次都減少10
}
ByteArrayInputStream isBm =newByteArrayInputStream(baos.toByteArray());//把壓縮後的數據baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm,null,null);//把ByteArrayInputStream數據生成圖片
returnbitmap;
}
二、圖片按比例大小壓縮方法(根據Bitmap圖片壓縮)
privateBitmap comp(Bitmap image) {
ByteArrayOutputStream baos =newByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG,100, baos);
if( baos.toByteArray().length /1024>1024) {//判斷如果圖片大於1M,進行壓縮避免在生成圖片(BitmapFactory.decodeStream)時溢出
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG,50, baos);//這里壓縮50%,把壓縮後的數據存放到baos中
}
ByteArrayInputStream isBm =newByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options newOpts =newBitmapFactory.Options();
//開始讀入圖片,此時把options.inJustDecodeBounds 設回true了
newOpts.inJustDecodeBounds =true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm,null, newOpts);
newOpts.inJustDecodeBounds =false;
intw = newOpts.outWidth;
inth = newOpts.outHeight;
//現在主流手機比較多是800*480解析度,所以高和寬我們設置為
floathh = 800f;//這里設置高度為800f
floatww = 480f;//這里設置寬度為480f
//縮放比。由於是固定比例縮放,只用高或者寬其中一個數據進行計算即可
intbe =1;//be=1表示不縮放
if(w > h && w > ww) {//如果寬度大的話根據寬度固定大小縮放
be = (int) (newOpts.outWidth / ww);
}elseif(w < h && h > hh) {//如果高度高的話根據寬度固定大小縮放
be = (int) (newOpts.outHeight / hh);
}
if(be <=0)
be =1;
newOpts.inSampleSize = be;//設置縮放比例
//重新讀入圖片,注意此時已經把options.inJustDecodeBounds 設回false了
isBm =newByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm,null, newOpts);
returncompressImage(bitmap);//壓縮好比例大小後再進行質量壓縮
}
⑥ Android Bitmap 內存以及OOM問題討論
都知道在Android中, 每個應用所使用的內存是有限的,現在的手機通常最大的內存使用為256M, 目前還沒發現Android中一個應用的最大內存分配超過256M的(經測試華為手機的最大內存是385M)
相關API:
ActivityManager.getMemoryClass(),首先獲取系統服務中的ActivityManager
如下:
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
可以獲取到相關信息
最近一直被項目的OOM問題困擾, 在網上查閱相關資料,前前後後讀了不下於30篇,這些篇幅講解的東西都是千篇一律,並沒有解決到實際問題
也在慕課網學習了內存優化章節
這是慕課網講師的PPT,我截屏的
這里來仔細分析一下:
第一個, 注意臨時Bitmap對象的及時回收, 來看下相關API
直接上圖
經過我無數次的使用Android studio工具自帶的MAT分析工具後, 得出一個很嚴謹的結論, 此方法並不奏效...
Android中Bitmap的內存存放在堆區, Google 的Bitmap的recycle方法注釋也可以了解到
Android歷史版本不是很清楚, 據說Android3.0之前Bitmap是存放在native區域,可以進行手動釋放,然而3.0之後Bitmap是存放在Java層的堆區,沒錯是heap, 內存管理直接交由系統GC管理,你還這樣釋放資源有意義?無非是給自己的一點心理安慰罷了, 告訴你沒卵用
又有人在說要釋放內存使用System.gc() ??? 對就是主動觸發垃圾回收,這個API是開發者自行調用的嗎?那麼系統管理內存還有什麼意義?這不是誤人子弟嗎,這個API不能調用的, 因為沒卵用的, 具體自己參照MAT工具自行分析.即便垃圾回收真的被觸發了, 所有線程停滯由系統來清理垃圾, 造成的後果是嚴重卡頓!!!
再看一個API:
我在網上苦苦追尋內存過高的問題後,發現了這個API,經過無數次實踐後我得出一個結論,沒卵用...開發者可以拋棄它
綜上所訴, 第一點講解的內存優化問題可以直接PASS掉, 無非給自己一點心理安慰: 我已經處理好了內存問題, 程序不會OOM?
第二點. 避免Bitmap的浪費
直接說結論, 這個是非常行之有效的,並且是一定能解決問題的
具體怎麼操作呢? 自己實現LruCache這個類, 就是這么弄, 原理就是解碼復用, 在內存中已經解碼好的Bitmap直接拿出來使用, 沒有的在載入到內存進行解析, 這個非常有效,但是並不能讓你避免OOM
第三點, try-catch某些大內存分配的操作
這點上,我又要開始疑問了, 我Java功底不是很好
Java中發生內存溢出時,拋出的是OutOfMemoryError, 它的父類是VirtualMachineError
這玩意能catch住? 它屬於Error范疇, 你能捕獲?請Java大神出來說一下,我解釋不清楚
第四點, 載入Bitmap 縮放比例, 解碼格式, 局部載入
先來分析一下縮放比例:
按照市面上主流的手機解析度來分析現在Android主流的解析度是1920X1080, 如果一個ImageView控制項剛好就是屏幕全屏,怎麼說?直接佔用掉8M內存, 想想一個實際的需求情況
一個查看大圖的頁面, 不斷的關閉,打開查看新的大圖,問題就來了,內存一直在暴增,遲早會突破界限OOM掉
解析度是2K屏呢? 更恐怖了, 隨著手機設備的屏幕解析度提升, 載入圖像需要的內存也是倍增的, 因為應用的最大內存並沒有增加
結論: 縮放比例可以有效的降低內存佔用問題, 但不是絕對的救命稻草, 該縮放的還是要縮放,而且必須縮放,就是采樣 現在通常都是圖片載入框架來完成,類似Glide.Picasso,Fresco等,他們可以幫助你減少工作量, 內存問題還是存在
再來分析一下解碼格式:
這個跟縮放比例效果差不多, 只是同樣的解析度的圖片載入到內存中時佔用內存減少了
比如ARGB_8888 共32位
RGB_565 共16位
ARGB_4444 共16位
很明顯這樣格式圖片載入的內存情況是ARGB_8888是其他格式的兩倍內存
另外的問題是ARGB_8888看起來很清晰的, 其它的看起來圖片有種糊了的感覺,自己選擇吧
結論, 降低內存佔用非常有效
最後一個是局部載入, 並沒有怎麼使用到,也不清楚就不說了
最後還有一個方法避免OOM, 開啟largeHeap屬性, 但是但是, 以前我們開啟這個屬性後被Oppo應用市場認定為佔用內存過高, 不建議用戶安裝......所以我們又取消了!
總的來說, Bitmap在內存是變現的是不可控, 我項目OOM問題一直沒有得到有效解決,因為圖片編輯視頻編輯之類的功能佔用內存過高,繼續使用OOM是必然的, 跟IOS的同學交流了一番,他們說IOS的應用內存可以佔用到1個G以上, 輕松跑到500M是沒問題的, IOS的內存機制可以持續給內存使用, 具體我也不清楚,並且他們可以手動釋放內存?malloc, free這樣子?
如果大家有比較好的方案,還望留言交流互相幫助 [笑臉.gif]
補充: Android8.0開始Bitmap數據內存存在native層, 單個應用可用的內存顯著增長, 極大的降低了OOM的概率(2018年3月22日)