out of memory error in file manager

半城伤御伤魂 提交于 2019-12-25 17:22:14

问题


I made a custom file manager, and it is working fine. but it is loading and scrolling very slowly and suddenly there was outofmemory error. I am adding images on the side of the text view

package com.example.fileexplorer;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class FileExplorer extends Activity {
    EditText et;
    ListView lv;
    ArrayList<Data> list;
    ArrayAdapter<Data> aa;
    LayoutInflater li;
    Context cv=this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file_explorer);
        et = (EditText) findViewById(R.id.et_main);
        lv = (ListView) findViewById(R.id.lv_main);
        list = new ArrayList<Data>();

        readFiles();

        li=(LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        aa=new ArrayAdapter<Data>(cv,android.R.layout.simple_list_item_1,list)
                {
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    // TODO Auto-generated method stub
                Data d=list.get(position);

                View v=li.inflate(R.layout.list_inflate, null);

                ImageView iv=(ImageView) v.findViewById(R.id.iv_inflate);
                TextView tv=(TextView) v.findViewById(R.id.tv_inflate);
                Bitmap icon = BitmapFactory.decodeResource(getResources(), d.id);
                icon = getdecodedimage(icon, 50, 50);
                iv.setImageBitmap(icon);
                tv.setText(d.f_name);
                tv.setTextColor(Color.BLACK);

                    return v;
                }

                };
                lv.setAdapter(aa);
    }

    private void readFiles()
    {
        File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
        File[] list_files = f.listFiles();
        Data d;
        for (int i = 0; i < list_files.length; i++) {
            d = new Data();
            if (list_files[i].isDirectory()) {
                d.f_name = list_files[i].getName().toString();
                d.id = R.drawable.folder;

                list.add(d);
            }

            // Detecting file extentions and giving appropriate image to it
            else if (list_files[i].isFile()) {

                int temp = (list_files[i].getName().lastIndexOf(".")) + 1;
                String extention = list_files[i].getName().substring(temp);

                if (extention.equalsIgnoreCase("img") || extention.equalsIgnoreCase("jpg")
                        || extention.equalsIgnoreCase("png")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.images;
                }

                else if (extention.equalsIgnoreCase("mp3") || extention.equalsIgnoreCase("wav")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.music;
                } 

                else if (extention.equalsIgnoreCase("mp4") || extention.equalsIgnoreCase("3gp")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.video;
                } 

                else if (extention.equalsIgnoreCase("doc")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.docx;
                } 

                else if (extention.equalsIgnoreCase("pdf")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.pdf;
                } 



                else if (extention.equalsIgnoreCase("txt")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.txt;
                } 

                else if (extention.equalsIgnoreCase("apk")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.apk;
                } 



                else if (extention.equalsIgnoreCase("xlsx")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.exel;
                } 

                else if (extention.equalsIgnoreCase("pptx")) {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.pptx;
                }
                else
                {
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.unknown;
                }

                list.add(d);
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.file_explorer, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_home) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    class FileHandlingAsync extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
        }

        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
        }
    }
    public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {

        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);

        // Mayur must
        // watch.........................................................
        // bm.recycle();
        // .....................................................................

        return resizedBitmap;
    }
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and
            // keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }
    Bitmap getdecodedimage(Bitmap bmp, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        ByteArrayOutputStream byteArrayBitmapStream = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 85, byteArrayBitmapStream);
        byte[] b = byteArrayBitmapStream.toByteArray();
        BitmapFactory.decodeByteArray(b, 0, b.length, options);

        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeByteArray(b, 0, b.length, options);

    }
}

[![this is the screenshot][1]][1]

The scroll is also very slow, how can I optimize it?


回答1:


Try to use LruCache

This code is working

package com.example.fileexplorer;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.util.LruCache;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class FileExplorer extends Activity implements OnItemClickListener {
    EditText et;
    ListView lv;
    ArrayList<Data> list;
    ArrayAdapter<Data> aa;
    LayoutInflater li;
    Context cv = this;
    String main_path = "/storage";
    File[] list_files;
    int exit_count = 0; // Double tap back key to exit
    ArrayList<Data>list_search;
    View v;

    private LruCache<Integer, Bitmap> mLrucatche;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file_explorer);


        final int maxMemory=(int) (Runtime.getRuntime().maxMemory()/1024);
        final int cacheSize=maxMemory/8;
        mLrucatche=new LruCache<Integer,Bitmap>(cacheSize){

            @Override
            protected int sizeOf(Integer key, Bitmap value) {
                // TODO Auto-generated method stub
                return value.getByteCount()/1024;
            }
        };


        et = (EditText) findViewById(R.id.et_main);
        et.setVisibility(View.GONE);
        lv = (ListView) findViewById(R.id.lv_main);
        list = new ArrayList<Data>();
        list_search=new ArrayList<Data>();
        lv.setOnItemClickListener(this);


        new FileHandlingAsync().execute(main_path);
        // readFiles(main_path);

        li = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        aa = new ArrayAdapter<Data>(cv, android.R.layout.simple_list_item_1, list) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // TODO Auto-generated method stub
                Data d = list.get(position);

                v = li.inflate(R.layout.list_inflate, null);

                ImageView iv = (ImageView) v.findViewById(R.id.iv_inflate);
                TextView tv = (TextView) v.findViewById(R.id.tv_inflate);

                Bitmap thumnailImage=null;

//              Bitmap icon = BitmapFactory.decodeResource(getResources(), d.id);
//              icon = getdecodedimage(icon, 50, 50);
//              iv.setImageBitmap(icon);

                // Making text short if more than 25 words...only for files
                if (d.f_name.length() > 25) {
                    if (!(list_files[position]).isDirectory()) {
                        d.f_name = d.f_name.substring(0, 22);
                        d.f_name = d.f_name + "...";
                    }
                }

                tv.setText(d.f_name);
                tv.setTextColor(Color.BLACK);
                //mayu
                int key=d.id;
                thumnailImage=getBitmapFromMcache(key);
                if(thumnailImage==null)
                {
                    BitmapWorkerTask task=new BitmapWorkerTask(iv);
                    task.execute(key);
                }
                iv.setImageBitmap(thumnailImage);
                return v;
            }

        };lv.setAdapter(aa);



        //Search feature
        et.addTextChangedListener(watcher);
    }

    public Bitmap getBitmapFromMcache(Integer id)
    {
        return mLrucatche.get(id);
    }

    public void addBitmapToMcache(Integer id,Bitmap bitmap)
    {
        if(getBitmapFromMcache(id)==null)
        {
            mLrucatche.put(id, bitmap);
        }
    }

    private void readFiles(String path) {
        File f = new File(path);
        list_files = f.listFiles();
        Data d;
        for (int i = 0; i < list_files.length; i++) {
            d = new Data();
            if (list_files[i].isDirectory()) {

                String name1=list_files[i].getName();
                name1=name1.substring(0, 1);

                //Removing directories which starts from "." or "$"
                if(name1.equals(".")||name1.equals("$"))
                {

                }else{
                d.f_name = list_files[i].getName().toString();
                d.id = R.drawable.folder;

                list.add(d);
                }
            }

            // Detecting file extentions and giving appropriate image to it
            else if (list_files[i].isFile()) {

                int temp = (list_files[i].getName().lastIndexOf(".")) + 1;
                String extention = list_files[i].getName().substring(temp);

                switch (extention) {
                case "img":
                case "jpg":
                case "jpeg":
                case "png": d.f_name = list_files[i].getName().toString();
                d.id = R.drawable.images;
                    break;

                    case "mp3":
                    case "wav":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.music;
                        break;
                    case "mp4":
                    case "3gp":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.video;
                        break;
                    case "doc":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.docx;
                        break;
                    case "pdf":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.pdf;
                        break;
                    case "txt":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.txt;
                        break;
                    case "apk":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.apk;
                        break;
                    case "xlsx":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.exel;
                        break;
                    case "pptx":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.pptx;
                        break;
                    case "zip":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.zip;
                        break;
                    case "rar":
                        d.f_name = list_files[i].getName().toString();
                        d.id = R.drawable.rar;
                        break;

                default:
                    d.f_name = list_files[i].getName().toString();
                    d.id = R.drawable.unknown;
                    break;
                }
                list.add(d);

            }
        }


    }

    //For search feature
    TextWatcher watcher=new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub



        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub

        }
    };


    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // TODO Auto-generated method stub

        if (list_files[position].isDirectory()) {
            Data d = list.get(position);
            String name = d.f_name;
            main_path = main_path + "/" + name;
            ArrayList<Data> temp_list = new ArrayList<Data>();
            temp_list.addAll(list);

            try {
                list.clear();
                new FileHandlingAsync().execute(main_path);
                // readFiles(main_path);
            } catch (Exception e) {
                list.addAll(temp_list);
                Toast.makeText(cv, "Cannot open", Toast.LENGTH_SHORT).show();
            }
            aa.notifyDataSetChanged();
        } else {
            Toast.makeText(cv, "Not a directory", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.file_explorer, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_search) {

            et.setVisibility(View.VISIBLE);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        // TODO Auto-generated method stub

        if (!(exit_count == 1)) {
            if (!main_path.equals("/storage")) {
                int index = main_path.lastIndexOf("/");
                main_path = main_path.substring(0, index);
                list.clear();
                readFiles(main_path);
                aa.notifyDataSetChanged();
            } else {
                exit_count++;
                Toast.makeText(cv, "Tap again to exit", Toast.LENGTH_SHORT).show();
            }
        } else {
            System.exit(0);
        }

    }

    class FileHandlingAsync extends AsyncTask<String, Void, Void> {

        ProgressDialog pd;

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            pd = new ProgressDialog(cv);
            pd.setMessage("Getting list of files...");
            pd.setCancelable(false);
            pd.show();
        }

        @Override
        protected Void doInBackground(String... params) {
            // TODO Auto-generated method stub
            String m_path = params[0];
            readFiles(m_path);

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            aa.notifyDataSetChanged();
            pd.dismiss();
        }

    }

    public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {

        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);

        // Mayur must
        // watch.........................................................
        // bm.recycle();
        // .....................................................................

        return resizedBitmap;
    }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and
            // keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

    Bitmap getdecodedimage(Bitmap bmp, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        ByteArrayOutputStream byteArrayBitmapStream = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 85, byteArrayBitmapStream);
        byte[] b = byteArrayBitmapStream.toByteArray();
        BitmapFactory.decodeByteArray(b, 0, b.length, options);

        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeByteArray(b, 0, b.length, options);

    }

    class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap>
    {
        private final WeakReference<ImageView> ivReference;

        public BitmapWorkerTask(ImageView imageview) {
            // TODO Auto-generated constructor stub
            ivReference=new WeakReference<ImageView>(imageview);
        }

        @Override
        protected Bitmap doInBackground(Integer... params) {
            // TODO Auto-generated method stub
            Bitmap bitmap=BitmapFactory.decodeResource(cv.getResources(),params[0]);
            addBitmapToMcache(Integer.valueOf(params[0]), bitmap);
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            // TODO Auto-generated method stub
            if(ivReference!=null || result!=null)
            {
                final ImageView imageview=(ImageView)ivReference.get();
                if(imageview!=null)
                {
                    imageview.setImageBitmap(result);
                }
            }

        }
    }

}

hope this helps u



来源:https://stackoverflow.com/questions/33235201/out-of-memory-error-in-file-manager

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!