NOTE:Android RuntimeException: Parcelle: incapable de rassembler la valeur
The code shown below may be a bit hard to read, but i hope it can help. Sorry for that.
Je reçois cette erreur chaque fois que j'appuyez sur la touche HOME et mon application s'en va arrière-plan.
java.lang.RuntimeException: Parcel: unable to marshal value [email protected]
Je suis nouveau à la programmation Android et je voudrais créer une classe qui peut me proposer toutes les fonctions sans les mettre en œuvre chaque fois.
J'ai fait une classe My_Activity:
package elektro_fr.my_android;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.WindowManager;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public abstract class My_Activity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener{
private int myLayout;
protected Bundle mySettings;
private boolean gesturesEnabled=false;
private GestureDetectorCompat myGestureDetector;
private boolean canStart=false;
private boolean menuEnabled=false;
private HashMap<String,Action> menuEntries;
protected List<My_Fragment> fragmentsList=new LinkedList<>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myGestureDetector = new GestureDetectorCompat(this,this);
if (savedInstanceState==null){
canStart=true;
}
init();
setContentView(myLayout);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("LIST",menuEntries);
for (int counter=0;counter<fragmentsList.size();counter++){
getSupportFragmentManager().putFragment(outState,"FRAGMENT_SETTINGS_"+counter,fragmentsList.get(counter));
}
}
@Override
protected void onStart() {
super.onStart();
if (canStart) setGraphics();
canStart=false;
}
protected abstract void init();
protected abstract void setGraphics();
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState!=null){
menuEntries=(HashMap<String, Action>) savedInstanceState.getSerializable("LIST");
int size=getSupportFragmentManager().getFragments().size();
for (int counter=0;counter<size;counter++){
fragmentsList.add(counter,(My_Fragment)getSupportFragmentManager().getFragment(savedInstanceState,"FRAGMENT_SETTINGS_"+counter));
}
}
refreshState();
}
abstract protected void refreshState();
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return menuEnabled;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if (menuEntries.get(item.getTitle())!=null){
menuEntries.get(item.getTitle()).doAction();
}
return menuEnabled;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
if (menuEnabled){
if (menuEntries.size()!=0){
menu.clear();
int counter=0;
for (String s: menuEntries.keySet()){
menu.add(Menu.NONE,counter,Menu.NONE,s);
counter++;
}
}
}
return menuEnabled;
}
protected void setGestures(boolean enabled){
gesturesEnabled=enabled;
}
protected void setMenu(boolean enabled){
menuEnabled=enabled;
menuEntries=new HashMap<>();
}
protected HashMap<String, Action> getMenuEntries(){
return menuEntries;
}
public My_Fragment addFragment(Class<? extends My_Fragment> fragmentClass, int fragmentContainer, int fragmentID, Bundle fragmentArgs){
My_Fragment fragment = null;
try {
fragment = fragmentClass.newInstance();
}
catch (InstantiationException e){
}
catch (IllegalAccessException e){
e.printStackTrace();
}
fragment.setArguments(fragmentArgs);
getSupportFragmentManager().beginTransaction().add(fragmentContainer, fragment).commit();
fragmentsList.add(fragment);
return fragment;
}
protected My_Fragment getFragment(Class<? extends My_Fragment> fragmentClass){
for (My_Fragment f: fragmentsList){
if (fragmentClass.isInstance(f)){
return f;
}
}
return null;
}
public void removeFragment(My_Fragment fragment,boolean addToBackStack){
if (fragment.isAdded()){
FragmentTransaction transaction=getSupportFragmentManager().beginTransaction();
if (addToBackStack)transaction.addToBackStack(null);
transaction.remove(fragment);
transaction.commit();
getSupportFragmentManager().executePendingTransactions();
if (!addToBackStack)fragmentsList.remove(fragment);
}
}
protected void setFullScreen(boolean fullScreen){
WindowManager.LayoutParams attrs = getWindow().getAttributes();
if (fullScreen) {
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
}
else {
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
}
getWindow().setAttributes(attrs);
}
protected void hideActionBar(boolean hidden){
if (hidden){
getSupportActionBar().hide();
}
else getSupportActionBar().show();
}
protected void setLayout(int layoutID){
myLayout=layoutID;
}
public boolean onTouchEvent(MotionEvent event) {
if (gesturesEnabled){
this.myGestureDetector.onTouchEvent(event);
}
return true;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
My_AndroidTools.KeyboardTools.closeInputKeyboard(getCurrentFocus());
return true;
}
public boolean onDoubleTap(MotionEvent e) {
return true;
}
public boolean onDoubleTapEvent(MotionEvent e) {
return true;
}
public boolean onDown(MotionEvent e) {
return true;
}
public void onShowPress(MotionEvent e) {
}
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return true;
}
public void onLongPress(MotionEvent e) {
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}
C'est FragmentsActivity, qui étend et met en œuvre My_Activity:
package elektro_fr.newapplication;
import android.os.Bundle;
import android.util.Log;
import android.widget.RelativeLayout;
import elektro_fr.my_android.Action;
import elektro_fr.my_android.My_Activity;
import elektro_fr.my_android.My_Fragment;
import elektro_fr.newapplication.R;
public class FragmentsActivity extends My_Activity implements My_Fragment.fragmentOperations {
private MyTopFragment topFragment;
private MyBottomFragment bottomFragment;
@Override
protected void init() {
setLayout(R.layout.fragments);
setGestures(true);
setMenu(true);
}
@Override
protected void setGraphics() {
Bundle args=new Bundle();
args.putInt(MyTopFragment.LAYOUT_ID,R.layout.ts_fragment);
args.putInt(My_Fragment.CENTER_HORIZONTAL,RelativeLayout.CENTER_HORIZONTAL);
topFragment = (MyTopFragment) addFragment(MyTopFragment.class,R.id.MainLayout,R.layout.ts_fragment,args);
Bundle args2=new Bundle();
args2.putInt(My_Fragment.LAYOUT_ID,R.layout.bs_fragment);
args2.putInt(My_Fragment.LAYOUT_WIDTH,RelativeLayout.LayoutParams.MATCH_PARENT);
args2.putInt(My_Fragment.LAYOUT_HEIGHT,RelativeLayout.LayoutParams.WRAP_CONTENT);
args2.putInt(My_Fragment.BELOW, R.id.ts);
args2.putInt(My_Fragment.CENTER_HORIZONTAL,RelativeLayout.CENTER_HORIZONTAL);
bottomFragment = (MyBottomFragment) addFragment(MyBottomFragment.class,R.id.MainLayout,R.layout.bs_fragment,args2);
getMenuEntries().put("Menu Item #1", new Action() {
@Override
public void doAction() {
Log.i("Ciccio","you pressed 1");
}
});
getMenuEntries().put("Menu Item #2", new Action() {
@Override
public void doAction() {
Log.i("Ciccio","you pressed 2");
}
});
getMenuEntries().put("Menu Item #3", new Action() {
@Override
public void doAction() {
Log.i("Ciccio","you pressed 3");
}
});
}
protected void refreshState(){
topFragment = (MyTopFragment) getFragment(MyTopFragment.class);
bottomFragment = (MyBottomFragment) getFragment(MyBottomFragment.class);
}
@Override
public void ClickButtonOperation(Object[] arguments) {
switch((Integer)arguments[0]){
case 0:
bottomFragment.setText((String)arguments[1],(String)arguments[2]);
break;
}
}
}
C'est classe My_Fragment:
package elektro_fr.my_android;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.text.Layout;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
public abstract class My_Fragment extends Fragment {
public final static String LAYOUT_ID="layout_id";
public final static String LAYOUT_WIDTH="layout_width";
public final static String LAYOUT_HEIGHT="layout_height";
public final static String BELOW="layout_below";
public final static String ABOVE="layout_above";
public final static String ALIGN_PARENT_BOTTOM="align_parent_bottom";
public final static String CENTER_HORIZONTAL="center_horizontal";
private String[] params={
LAYOUT_ID,LAYOUT_WIDTH, LAYOUT_HEIGHT, ALIGN_PARENT_BOTTOM, CENTER_HORIZONTAL, BELOW, ABOVE
};
protected int fragmentLayout;
protected fragmentOperations myActivity;
protected Bundle mySettings;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState!=null){
mySettings=new Bundle();
mySettings.putAll(savedInstanceState);
}
else mySettings=getArguments();
fragmentLayout=mySettings.getInt(LAYOUT_ID);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mySettings.putAll(savedInstanceState);
refreshState();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
setState();
outState.putAll(mySettings);
}
public interface fragmentOperations{
void ClickButtonOperation(Object[] arguments);
}
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(fragmentLayout,container,false);
int widthSettings=mySettings.getInt(params[1]);
int heightSettings=mySettings.getInt(params[2]);
view.setLayoutParams(new RelativeLayout.LayoutParams((widthSettings==0?RelativeLayout.LayoutParams.WRAP_CONTENT:widthSettings),(heightSettings==0?RelativeLayout.LayoutParams.WRAP_CONTENT:heightSettings)));
RelativeLayout.LayoutParams layoutConfig= (RelativeLayout.LayoutParams) view.getLayoutParams();
for (int counter=3;counter<params.length;counter++){
int settings=mySettings.getInt(params[counter]);
if (settings!=0){
if (counter==5){
layoutConfig.addRule(RelativeLayout.BELOW,settings);
}
else if (counter==6){
layoutConfig.addRule(RelativeLayout.ABOVE,settings);
}
else{
layoutConfig.addRule(settings);
}
}
}
init(view);
return view;
}
protected abstract void init(View v);
protected abstract void setState();
protected abstract void refreshState();
@Override
public void onAttach(Context context) {
super.onAttach(context);
myActivity=(fragmentOperations)getActivity();
}
}
EDIT:
Enfin, Action (interface), que j'edited afin de mettre en œuvre Serializable:
package elektro_fr.my_android;
import java.io.Serializable;
public interface Action extends Serializable{
public void doAction();
}
C'est l'erreur:
Process: elektro_fr.newapplication, PID: 24970 java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = elektro_fr.newapplication.FragmentsActivity$3)
Causée par:
Caused by: java.io.NotSerializableException: elektro_fr.newapplication.FragmentsActivity
pourquoi je implémente sérialisable dans cette classe?
StackOverflow ne fonctionne pas comme un forum classique, il est un Q & A du site.S'il vous plaît modifier la question et supprimer le _ (résolu) _ du titre et aussi la solution. Ajoutez la solution en utilisant le bouton "Répondre à votre question" ci-dessous. Et pour l'avenir gardez à l'esprit de publier seulement la quantité minimale de code nécessaire pour déclencher le problème. – perissf
@perissf Merci de l'avoir dit. J'ai édité mon post. Malheureusement, je ne savais pas où le problème pourrait être, alors je pensais que donner le code entier aurait été une bonne idée. –