Draco157
Draco157

Reputation: 15

Loading an image into an imageview causes "I/Choreographer: Skipped 139 frames! The application may be doing too much work on its main thread." error

I am taking a picture using camera intent and then using that image to display it in my app fragment. The image will load but causes massive performance problems and causes the app run very badly while the image is on screen. I have tried to implement threads to solve the problem but it is still happening. In the logcat I am getting "I/Choreographer: Skipped 175 frames! The application may be doing too much work on its main thread" warnings. Any help to solve this problem would be appreciated.

I am doing the threading in my OnActivityResults method as this is where the image is being displayed.

Camera_fragment class

public class Camera_Fragment extends Fragment {

private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 0;
private ImageView imageView;

public Camera_Fragment() {
    // Required empty public constructor
}

private String pictureImagePath = "";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = timeStamp + ".png";

    File mydir = getExternalStoragePublicDirectory("app image folder"); //Creating an internal dir;
    if (!mydir.exists())
    {

        {
            mydir.mkdirs();
        }
    }
    isReadPermissionGranted();
    pictureImagePath = mydir.getAbsolutePath() + "/" + imageFileName;
    File file = new File(pictureImagePath);
    Uri outputFileUri = Uri.fromFile(file);
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
    Fragment frag = this;
    frag.getActivity();
    /** Pass your fragment reference **/
    frag.startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); // REQUEST_IMAGE_CAPTURE = 12345

}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    final View rootView = inflater.inflate(R.layout.camera_layout_fragment, container, false);

    imageView = (ImageView) rootView.findViewById(R.id.imageView1);
    return rootView;
}

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

    if (requestCode == 1) {
        final File imgFile = new  File(pictureImagePath);
        if(imgFile.exists()){

            getActivity().runOnUiThread(new Runnable() {
                public void run() {
                    final Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
                    imageView.setImageBitmap(myBitmap);
                }
            });
        }
    }
}

public  boolean isStoragePermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(this.getContext(),android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG,"Permission is granted");
            return true;
        } else {

            Log.v(TAG,"Permission is revoked");
            ActivityCompat.requestPermissions(this.getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    }
    else { //permission is automatically granted on sdk<23 upon installation
        Log.v(TAG,"Permission is granted");
        return true;
    }
}


public  boolean isReadPermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(this.getContext(), Manifest.permission.READ_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG,"Permission is granted");
            return true;
        } else {

            Log.v(TAG,"Permission is revoked");
            ActivityCompat.requestPermissions(this.getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
            return false;
        }
    }
    else { //permission is automatically granted on sdk<23 upon installation
        Log.v(TAG,"Permission is granted");
        return true;
    }
}
   }

LogCat

    04-16 22:06:44.023 5043-5207/com.keith.draco.crecheapp I/OpenGLRenderer:               
    Initialized EGL, version 1.4
    04-16 22:06:44.252 5043-5043/com.keith.draco.crecheapp W/art: Before 
    Android 4.1, method int 
    android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, 
    boolean) would have incorrectly overridden the package-private method in 
    android.widget.ListView
    04-16 22:06:48.553 5043-5207/com.keith.draco.crecheapp D/OpenGLRenderer: 
    endAllActiveAnimators on 0xb90e4e30 (RippleDrawable) with handle 
    0xb90e6150
    04-16 22:06:49.345 5043-5043/com.keith.draco.crecheapp W/PathParser: 
    Points are too far apart 4.000000596046461
    04-16 22:06:49.348 5043-5043/com.keith.draco.crecheapp W/PathParser: 
    Points are too far apart 4.000000596046461
    04-16 22:06:50.529 5043-5043/com.keith.draco.crecheapp W/PathParser: 
    Points are too far apart 4.000000596046461
    04-16 22:06:50.531 5043-5043/com.keith.draco.crecheapp W/PathParser: 
    Points are too far apart 4.000000596046461
    04-16 22:06:50.546 5043-5043/com.keith.draco.crecheapp V/ContentValues:  
    Permission is granted
    04-16 22:07:05.917 5043-5043/com.keith.draco.crecheapp       
    I/ListPopupWindow: Could not find method setEpicenterBounds(Rect) on 
    PopupWindow. Oh well.
    04-16 22:07:08.389 5043-5043/com.keith.draco.crecheapp I/Choreographer: 
    Skipped 142 frames!  The application may be doing too much work on its 
    main thread.
    04-16 22:07:10.764 5043-5043/com.keith.draco.crecheapp I/Choreographer: 
    Skipped 138 frames!  The application may be doing too much work on its 
    main thread.
    04-16 22:07:15.869 5043-5043/com.keith.draco.crecheapp I/Choreographer: 
    Skipped 135 frames!  The application may be doing too much work on its 
    main thread.

Upvotes: 1

Views: 153

Answers (1)

CommonsWare
CommonsWare

Reputation: 1007554

There are many image-loading libraries available for Android, that can load your image asynchronously. Please consider using one, such as Picasso.

If you wish to do this yourself, you will need to arrange to perform your decodeFile() on a background thread, before calling setImageBitmap() on the main application (UI) thread.

Upvotes: 1

Related Questions