Hi I used fragment A and second fragment used b. a call to b and in used asynctask
method but I used this first time it is perfectly worked but second time then crash the app and my error log in below ::: I worked Samsung tablet perfect worked but Samsung core mobile in crash the app.
E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
E/AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1343)
E/AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1361)
E/AndroidRuntime: at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
E/AndroidRuntime: at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
E/AndroidRuntime: at com.buymysari.fragment.SendImageServerFragment$SendImageServerTask.onPostExecute(SendImageServerFragment.java:158)
E/AndroidRuntime: at com.buymysari.fragment.SendImageServerFragment$SendImageServerTask.onPostExecute(SendImageServerFragment.java:1)
E/AndroidRuntime: at android.os.AsyncTask.finish(AsyncTask.java:631)
E/AndroidRuntime: at android.os.AsyncTask.access$600(AsyncTask.java:177)
E/AndroidRuntime: at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:4960)
E/AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
E/AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
My Class used in:
public class TakeCameraFragment extends Fragment {
Camera mCamera = null;
private CameraPreview mCameraPreview;
protected static final int MEDIA_TYPE_IMAGE = 0;
static String FilePAth = "";
Button takePicture;
static String base64string = "";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.camerafragment,
container, false);
mCamera = getCameraInstance();
Log.v("log_tag", "mCamera :: " + mCamera);
mCameraPreview = new CameraPreview(getActivity(), mCamera);
FrameLayout preview = (FrameLayout) rootView
.findViewById(R.id.camera_preview_fragment);
preview.addView(mCameraPreview);
takePicture = (Button) rootView
.findViewById(R.id.btnTakePicturefragment);
takePicture.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCamera.takePicture(null, null, mPictureframent);
}
});
return rootView;
}
public boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
releaseCamera();
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
private Camera getCameraInstance() {
try {
Log.v("log_tag", "camera try:::" + mCamera);
mCamera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
Log.v("log_tag", "camera catch:::" + mCamera);
releaseCamera();
}
return mCamera;
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraAppFragment");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
FilePAth = mediaStorageDir.getPath() + File.separator + "IMG_fragment_"
+ timeStamp + ".jpg";
Log.v("log", " FilePAth " + FilePAth);
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_fragment_" + timeStamp + ".jpg");
return mediaFile;
}
PictureCallback mPictureframent = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
SetPictureImageFragment fm2 = new SetPictureImageFragment();
fragmentTransaction.replace(R.id.relative_camerafragment_id,
fm2, "HELLO");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Bundle bundle = new Bundle();
bundle.putByteArray("position", data);
fm2.setArguments(bundle);
mCamera.startPreview();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
}
Second Fragment used:
public class SetPictureImageFragment extends Fragment {
ImageView img;
Bundle bundle;
byte[] path;
byte[] byteArrayimage;
Button conform;
float x;
Bitmap b;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.capturepicturefragment, null);
Log.v("log_tag","SetPictureImageFragment");
bundle = this.getArguments();
path = bundle.getByteArray("position");
Log.v("log_tag","SetPictureImageFragment ::: Path :: "+path);
img = (ImageView) view.findViewById(R.id.camera_preview_fragment_imageview);
conform=(Button)view.findViewById(R.id.conform);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true; // inPurgeable is used to free up
// memory while required
Bitmap b = BitmapFactory.decodeByteArray(path, 0,path.length,options);
int width = b.getWidth();
int height = b.getHeight();
int newWidth = 500;
int newHeight = 500;
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
int finalDegree = 0;
if(rotation == 0) {
finalDegree = 90;
}
if(rotation == 1) {
finalDegree = 270;
}
if(rotation == 2) {
finalDegree = 180;
}
if(rotation == 3) {
finalDegree = 90;
}
matrix.postRotate(finalDegree);
Bitmap resizedBitmap = Bitmap.createBitmap(b, 0, 0,width, height, matrix, true);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byteArrayimage = stream.toByteArray();
img.setScaleType(ScaleType.CENTER);
img.setImageBitmap(resizedBitmap);
conform.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentManager fm = getChildFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
SendImageServerFragment fm2 = new SendImageServerFragment();
// CreateStoreFragment fm2 = new CreateStoreFragment();
fragmentTransaction.replace(R.id.relative_cameraimageview_fragment, fm2,
"HELLO");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Bundle bundle = new Bundle();
bundle.putByteArray("position", byteArrayimage);
fm2.setArguments(bundle);
}
});
return view;
}
}
Third Fragment used:::
public class SendImageServerFragment extends Fragment {
SegmentedRadioGroup segmentText;
SegmentedRadioGroupMale segmentTextMale;
Button sendImg;
EditText edt_txt;
MyApplication app;
View view;
Bundle bundle;
byte[] path;
String base64string = "";
Bitmap b;
String cat_id = "";
String gender = "";
private ProgressDialog progress;
InputMethodManager mgr;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
}
view = inflater.inflate(R.layout.sendimageserver, null);
// view.setFocusableInTouchMode(true);
// view.requestFocus();
bundle = this.getArguments();
path = bundle.getByteArray("position");
segmentText = (SegmentedRadioGroup) view
.findViewById(R.id.segment_text);
segmentTextMale = (SegmentedRadioGroupMale) view
.findViewById(R.id.segment_text_male);
sendImg = (Button) view.findViewById(R.id.btn_send_image);
edt_txt = (EditText) view.findViewById(R.id.edt_text_store_name);
edt_txt.requestFocus();
mgr = (InputMethodManager) getActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(edt_txt, InputMethodManager.SHOW_IMPLICIT);
app = (MyApplication) getActivity().getApplicationContext();
sendImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int segTxt = segmentText.getCheckedRadioButtonId();
RadioButton radiocatButton = (RadioButton) view
.findViewById(segTxt);
int segmentTextMaleTxt = segmentTextMale
.getCheckedRadioButtonId();
RadioButton radioSexButton = (RadioButton) view
.findViewById(segmentTextMaleTxt);
// b = BitmapFactory.decodeByteArray(path, 0, path.length);
base64string = Base64.encodeToString(path, Base64.DEFAULT);
if (radiocatButton.getText().toString().equals("S")) {
cat_id = "4";
} else if (radiocatButton.getText().toString().equals("C")) {
cat_id = "1";
} else if (radiocatButton.getText().toString().equals("A")) {
cat_id = "5";
}
if (radioSexButton.getText().toString().equals("M")) {
gender = "Male";
} else if (radioSexButton.getText().toString().equals("F")) {
gender = "Female";
}
progress = new ProgressDialog(getActivity());
progress.setMessage("Loading...");
new SendImageServerTask(progress).execute("Home");
}
});
return view;
}
public class SendImageServerTask extends AsyncTask<String, Void, String> {
public SendImageServerTask(ProgressDialog progress) {
progress = progress;
}
public void onPreExecute() {
progress.show();
}
@Override
protected String doInBackground(String... arg) {
String msg = DBAdpter.userUpdateImageStore(app.getStoreId(),
edt_txt.getText().toString(), cat_id, base64string, gender);
Log.v("log_tag", " Msg " + msg);
return msg;
}
@Override
protected void onPostExecute(String result) {
// Create here your JSONObject...
progress.dismiss();
Toast.makeText(getActivity().getApplicationContext(), result,
Toast.LENGTH_LONG).show();
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
StoreProfileGridFragment fm2 = new StoreProfileGridFragment();
fragmentTransaction.replace(R.id.relative_sendimage_send, fm2,
"HELLO");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
hideKeybord(edt_txt);
}
}
public void hideKeybord(View view) {
mgr.hideSoftInputFromWindow(view.getWindowToken(),
InputMethodManager.RESULT_UNCHANGED_SHOWN);
}
}
try { activity.getSupportFragmentManager ().popBackStackImmediate (name); } catch (IllegalStateException ignored) { // There's no way to avoid getting this if saveInstanceState has already been called. } This is enough to stop the app from crashing.
It's October 2017, and Google makes Android Support Library with the new things call Lifecycle component. It provides some new idea for this 'Can not perform this action after onSaveInstanceState' problem. Use lifecycle component to determine if it's correct time for popping up your fragment.
So in short, if you ever see this happens on your end, it’s likely that some of your fragment transaction is called after onSaveInstanceState (). You’ll need to then debug your flow see how that could occur. Understanding how this happens, we’ll look at the flow of our program. due to the checkPermissionAndRequest () functionality.
This exception will be thrown when activity's configuration changed and fragment onSavedInstanceState () is called and thereafter your async callback method tries to commit fragment. Simple solution could be check whether activity is changing configuration or not
It is known as state loss. You happen to commit a FragmentTransaction from AsyncTask. That is prohibited by the framework itself.
If you are okay with the possibility of state loss and behaviour unexpected by user, you could use
FragmentTransaction#commitAllowingStateLoss()
instead of
FragmentTransaction#commit()
Anyway, consider reading the link I provided, it is a very common situation.
Edit: Also, there is a workaround of your problem. But I guess, the consequences of this lead to a possible state loss, too. Nonetheless:
Declare a Handler
in your Fragment
:
private Handler handler = new Handler();
Then, in your onPostExecute(..)
do this:
@Override
protected void onPostExecute(String result) {
progress.dismiss();
Toast.makeText(getActivity().getApplicationContext(), result,
Toast.LENGTH_LONG).show();
handler.post(new Runnable() {
@Override
public void run() {
hideKeybord(edt_txt);
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
StoreProfileGridFragment fm2 = new StoreProfileGridFragment();
fragmentTransaction.replace(R.id.relative_sendimage_send, fm2,
"HELLO");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With