Reputation: 15
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
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