1. 程式人生 > >淺談Android多圖(包括大圖)上傳時的記憶體處理,防止記憶體溢位。

淺談Android多圖(包括大圖)上傳時的記憶體處理,防止記憶體溢位。

Android多圖上傳時,為了防止記憶體溢位,基本只要做好兩點就好了,一是及時釋放已經上傳完的圖片,以及在對圖片處理時,必須是一張一張來,因為對圖片的處理過程是最容易OOM的。

下面有簡單的程式碼說明下,

1、首先,圖片的model,

ImageBean

model中儲存bitmap物件,然後寫好回收方法。

然後,上傳大致分為路徑上傳,還有壓縮後以byte[]的方式上傳,

所以也要有path和byte[]

    public String path;
    public Bitmap bitmap;
    public byte[] result;
    public Bitmap getBitmap() {
        if (bitmap == null || bitmap.isRecycled()) {
            try {
                //bitmap = MyBimp.revitionImageSize(path, rotation);
                bitmap = MyBimp.getBitmapFromFile(path, rotation);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return bitmap;
    }

    public void recy() {
        if (bitmap != null) {
            if (!bitmap.isRecycled()) {
                bitmap.recycle();
            }
            bitmap = null;
        }
        if (result != null)
            result = null;
    }

    public static byte[] Bitmap2Bytes(Bitmap image, long size) {
        try {
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                long max = 1024 * 1024 + 3072;
                if (size > max) {
                    int options = 100;
                    while (baos.toByteArray().length > (size * 0.8)) {
                        baos.reset();
                        options -= 10;
                        image.compress(Bitmap.CompressFormat.JPEG, options, baos);
                    }
//                    Log.i("TAG", "Utils bitmap option " + options);
                    if (image.isRecycled())
                        image.recycle();

                    return baos.toByteArray();
                } else {
                    return baos.toByteArray();
                }
            } catch (NullPointerException ex) {
                ex.printStackTrace();
            }
        } catch (OutOfMemoryError ex) {
            ex.printStackTrace();
        }
        return null;
    }
<pre name="code" class="java">    public static Bitmap getBitmapFromFile(String path, int rotation) throws IOException {
        if (path == null)
            return null;
        try {
            try {
                BufferedInputStream in = new BufferedInputStream(new FileInputStream(
                        new File(path)));
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(in, null, options);
                in.close();
                WeakReference<Bitmap> weakReference = new WeakReference<Bitmap>(BitmapFactory.decodeFile(path));
                if (weakReference.get() != null) {
                    Bitmap bitmap = Bitmap.createScaledBitmap(weakReference.get(), options.outWidth, options.outHeight, true);
                    if (rotation != 0 && bitmap != null) {
                        Matrix m = new Matrix();
                        m.setRotate(rotation);
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
                    }
                    return bitmap;
                }
            } catch (NullPointerException ex) {
                ex.printStackTrace();
            }
        } catch (OutOfMemoryError ex) {
            ex.printStackTrace();
        }
        return null;
    }


壓縮程度根據自己專案實際情況來控制。

2、從相簿讀取圖片,應該只讀取了手機中圖片的路徑等相關資訊,然後壓縮顯示,這些程式碼往上非常多。

目的只有一個,不佔用多餘的記憶體,

所以只有真正要上傳的圖片,才會生成完整的bitmap物件或byte[]陣列。

可以建立一個全域性的MyBimp類,用來管理相簿圖片,已選擇的圖片等等。

 public static ArrayList<ImageBean> tempSelectBitmap = new ArrayList<ImageBean>(); 

選擇完圖片後,應該是一個List<ImageBean>陣列。3、上傳,保證單例上傳,然後每上傳完一個呼叫model中的回收方法就好了,

public class UploadTool {
    private static UploadTool uploadTool = null;

    private UploadTool() {
    }

    public static UploadTool getInstance() {

        if (uploadTool == null) {
            uploadTool = new UploadTool();
        }
        return uploadTool;
    }

    int len;// = MyBimp.tempSelectBitmap.size();
    List<ImageModel> list = new ArrayList<>();
    int position;

    private synchronized void upload(final int next, final onUploadImagesListenter listenter) {
        listenter.onProgressUpdate(next, len);
        if (next < len) {
            ImageBean item = MyBimp.tempSelectBitmap.get(next);
            if (next > 0) {
                MyBimp.tempSelectBitmap.get(next - 1).recy();
            }
            if (!item.isLarge) {
                item.getBitmapLocal(new ImageBean.onBitmapLoadListener() {
                    @Override
                    public void onBitmapLoad(byte[] result) {
                        if (result != null) {
                            //以byte[]上傳
                        } else {
                            String error = "資料錯誤";
                            listenter.onUploadDone(list, error);
                        }
                    }
                });
            } else {
                //以路徑上傳  一般長圖會以這種方式上傳
            }
        }
    }

    public void uploadImages(final onUploadImagesListenter listenter) {
        len = MyBimp.tempSelectBitmap.size();
        position = 0;
        upload(0, listenter);
    }


    public interface onUploadImagesListenter {
        void onUploadDone(List<ImageModel> imageModelList, String error);

        void onProgressUpdate(int position, int tatol);
    }
}

具體的上傳方法沒有寫進來,這個根據自己需求不同有很多種不同的方式,比如第三方的sdk。

原始碼:https://github.com/kiwilll/Album-and-Picture-upload


相關推薦

Android包括記憶體處理防止記憶體溢位

Android多圖上傳時,為了防止記憶體溢位,基本只要做好兩點就好了,一是及時釋放已經上傳完的圖片,以及在對圖片處理時,必須是一張一張來,因為對圖片的處理過程是最容易OOM的。 下面有簡單的程式碼說明下, 1、首先,圖片的model, ImageBean model中

android中載入高清及圖片壓縮方式(二)

  這一講就是本系列的第二篇,一起來聊下關於android中載入高清大圖的問題,我們都知道如果我們直接載入原圖的話,一個是非常慢,需要等待一定時間,如果沒有在一定的時間內給使用者響應的話,將會極大影響使用者的體驗。另一個是如果你的手機記憶體小的話,可能會直接崩潰。這也就是直

基於Bootstrap的圖片檔案也可以、預覽、刪除、縮放、進度...顯示

一、引用js、css 二、Html程式碼 <input id="myFile" type="file" name="myFile" multiple class="file-loading

Android中Callback回撥的使用

今天專案的Bug基本修改完成了,於是就對自己還未了解的回撥函式進行了學習。回撥其實就是在一定的時間裡做“一件事”,至於“這件事”具體做的是什麼不會管,只管做“這件事“,比如Boss叫員工去吃飯,但每個員工可能吃不同的食物。只不過,回撥是對介面而言。簡單來說就是,A物件呼叫

Android應用保護Android應用逆向的基本方法

對於未進行保護的Android應用,有很多方法和思路對其進行逆向分析和攻擊。使用一些基本的方法,就可以打破對應用安全非常重要的機密性和完整性,實現獲取其內部程式碼、資料,修改其程式碼邏輯和機制等操作。這篇文章主要介紹一些基本的應用逆向和分析方法,演示Android應用的程式

JavaScript的事件事件類型

元素 滾動 鍵盤 合成 html 另一個 date mov 焦點事件   Web瀏覽器能夠發生的事件有很多種類型,不同的事件類型有不同的事件信息。DOM3級的事件類型主要包括:UI事件,用戶與頁面上的元素交互時觸發;焦點事件,元素獲得或失去焦點觸發;鼠標事件,用戶通過鼠標在

JavaScript的事件事件委托

沒有 str 方法 比較 獲取 ack 使用 點擊 通過   事件處理程序為Web程序提供了系統交互,但是如果頁面中的事件處理程序太多,則會影響頁面的性能。每個函數都是對象,都會占用內存,內存中對象越多,性能越差。需要事先為DOM對象指定事件處理程序,導致訪問DOM的次數增

JAVA位元組流讀寫檔案

InputStream  此抽象類是表示位元組輸入流的所有類的超類。需要定義 InputStream 的子類的應用程式必須始終提供返回下一個輸入位元組的方法。  int available()  返回此輸入流方法的下一個呼叫方可以不受阻塞地從此輸入流讀取(或跳過)的位

支援向量機Support Vector Machine

自從在學校安定下來後,小編的學習效率和時長提高了不少。在最近五天的時間裡,看了大約20節視訊並做了對應章節的程式設計練習。上一篇文章介紹了欠擬合和過擬合的知識,這次給小夥伴們介紹下支援向量機的知識。支援向量機和邏輯迴歸(Logistic Regression)很相像,從一方面

深入學習js之作用域之eval()和with

在深入學習js之淺談作用域(一)中 將作用域定義為一套規則,用來管理引擎如何在當前作用域以及巢狀的子作用域中根據識別符號名稱進行變數查詢。 作用域分為兩種主要的工作模式:1.詞法作用域(大多數程式語言包括js) 2.動態作用域(Bash指令碼、Perl中的一些模式) 1.

在LinuxRedhat 6.4安裝配置telnet服務並使用SecureCRT連線

由於之前在電腦上安裝了虛擬機器,並在虛擬機器中安裝了Linux,但是由於沒辦法直接複製螢幕內容,有時候做記錄顯得有些不方便。因此今天在電腦上安裝了一個SecureCRT,並在Linux上安裝了telnet服務,用於連線虛擬機器中的Linux,之後便可以更方便複製

基於SpringMVC的檔案增刪改查、下載、更新、刪除

一、專案背景    摘要:最近一直在忙著專案的事,3個專案過去了,發現有一個共同的業務,那就是附件的處理,附件包括各種文件,當然還有圖片等特殊檔案,由於時間的關係,每次都是匆匆忙忙的搞定上線,稱這專案的空檔,整理了一份附件上傳、下載、刪除的專案,主要就是附件的處理,情況包含以下幾種:   1. 表單個附件共存

Android Bitmap圖片處理防止記憶體溢位

在android 中載入一張圖片,如果圖片過大就有可能會出現記憶體溢位,特別是在載入資料過多的時候,像ListView 和GridView等重複列表中,因此在處理Android圖片防止記憶體溢位就顯得特別的重要,也是很多面試中經常問到的問題,面試官通常都會讓你談

Springboot 打成jar執行圖片到伺服器客戶端可直接通過url訪問

本地測試時,直接上傳圖片到resources/static 檔案下沒有問題,但是打成jar後,直接報錯 @RequestMapping(value = "/oldUploadImage",method = RequestMethod.POST) p

【OSS】檔案實際就是Object下載操作

package com.ls; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream;

Android中的組播(播)

-1 ip協議 strong 多個 接受 端口 ui線程 nbsp 數據 組播使用UDP對一定範圍內的地址發送相同的一組Packet,即一次可以向多個接受者發出信息,其與單播的主要區別是地址的形式。IP協議分配了一定範圍的地址空間給多播(多播只能使用這個範圍內

Android開發實戰二十一android:clipChildren屬性

.cn viewpage port 部分 lap ole 有一個 默認 版本 原文:Android開發實戰(二十一):淺談android:clipChildren屬性實現功能: 1、APP主界面底部模塊欄 2、ViewPager一屏多個界面顯示 3、........

C++型實現原理虛繼承的奧祕

大夥都知道,如果要實現C++的多型,那麼,基類中相應的函式必須被宣告為虛擬函式(或純虛擬函式)。舉個例子: class Point { public: Point(float x = 0.0, float y = 0.0) : _x(x), _y(y) { } virtual fl

Android MVP設計模式簡單結合RxJava+Retrofit

什麼是MVP 為什麼要用MVP 怎麼去完成一個MVP的設計呢 demo例項功能雖小五臟俱全 準備工作 View的基類

Android之SurfaceFlinger相關介紹

3.3 Surface Java層相關封裝 主要介紹三個類,對應如下: Java C++ SurfaceSession.java SurfaceComposeClient 對應JNI檔案為: android_view_surfacesession.cpp