简体   繁体   中英

Android what's the most efficient way to save and load images?

I have an app where the user picks an image from either the cloud, internal storage or external storage. The app then saves the image to the device and then stores the file path to a sqlite database. It then later uses the Picasso library to load the image from the file path. My problem is that when it goes to load the image from the file path, it loads it extremely slow. After saving the image, it takes maybe a minute to finally display it.

My question is: What is the most efficient way to save and load images chosen by a user. I would like it to load the images faster.

Here is my code:

Method that gets the result of the Intent for user to choose image

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK) 
    {

        if(requestCode == 1)
        {
            try {
                if (bitmap != null)
                {
                    bitmap.recycle();
                }

                InputStream stream = getContentResolver().openInputStream(data.getData());
                bitmap = BitmapFactory.decodeStream(stream);
                stream.close();

                Picasso.with(getBaseContext()).load(data.getData()).fit().centerInside().into(imageButton);
                imageButton.setBackground(null);

            } 
            catch (FileNotFoundException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }

        pictureSelected = true;

        SaveImageTask saveBitmap = new SaveImageTask(bitmap);
        saveBitmap.execute();

    }
}

Async Task to do the image saving

    private class SaveImageTask extends AsyncTask<Void, Integer, Boolean> {

    private Bitmap bitmap;

    SaveImageTask(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

    @Override
    protected Boolean doInBackground(Void...params) {

        // Create a media file name
        Calendar c = Calendar.getInstance();
        String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(c.getTime());
        String mImageName = "MT_"+ timeStamp +".jpg";
        String albumName = "My App";

        File file = null;

        String state = Environment.getExternalStorageState();

        // If there is external storage, save it in the pictures album. If not, save on internal storage
        if(Environment.MEDIA_MOUNTED.equals(state))
        {
            file = new File(addEdit.this.getExternalFilesDir(
                    Environment.DIRECTORY_PICTURES), albumName);
            if(!file.mkdirs())
            {
                file = new File(addEdit.this.getFilesDir(), mImageName);
            }
        }
        else
        {
            file = new File(addEdit.this.getFilesDir(), mImageName);
        }


        OutputStream fOut = null;
        try {
            fOut = new FileOutputStream(file);
            fOut.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        try {
            FileOutputStream fos = new FileOutputStream(file);
            filePath = file.getAbsolutePath();
            Log.v("Filepath", filePath);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.close();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
            return false;
        }
        catch(IOException e)
        {
            e.printStackTrace();
            return false;
        }


        return true;

     }

     protected void onProgressUpdate(Integer... progress) {
     }

     protected void onPostExecute(Boolean success) {
     }

 }

How I load the file path

if(person.getImage() != null)
    {
        //convert byte to bitmap take from contact class
        File imgFile = new File (person.getImage());
        if(imgFile.exists())
        {
            Picasso.with(getBaseContext()).load(imgFile).fit().centerInside().into(imageView);
        }
    }

Any advice would be greatly appreciated. Thank you.

one option would be to cache image thorugh WeakRefrence in that way you can keep image in memory and if image is not in memory then load from sdcard

i think below links can help you

weakReference and other weak reference for cache

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM