Android Fragment De Fuites De Mémoire
Je suis en train de faire une petite application que dans mon sparetime et je suis en utilisant de nombreux fragments. Je suis assez nouveau à l'fragments toutefois, j'ai utilisé de nombreuses ressources pour l'utilisation du bien... ou alors j'ai pensé. Je reçois des fuites de mémoire comme mon tas continue de croître que j'ai du changer de parcelle à parcelle. J'ai eu mon application mis en œuvre avec des Activités auparavant et j'avais réduit les fuites de mémoire de manière significative. Cependant, maintenant que je vais rejoindre le fragment de monde j'ai l'impression que si je commence à la case départ quand il s'agit de la mémoire.
MainActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//Setting the content view of the Activity
setContentView(R.layout.main);
//Setting up the actionbar.
ActionBar actionbar = getActionBar();
actionbar.setSubtitle("");
actionbar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME
| ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
actionbar.setTitle("");
actionbar = null;
MainMenuFragment frag = new MainMenuFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, frag).commit();
}
Ce MainActivity définit aussi l'ActionBar.
MainMenuFragment.java
public class MainMenuFragment extends Fragment implements OnClickListener, LoaderCallbacks<Cursor> {
private static final String TAG = "MainMenuFragment";
SharedPreferences.Editor prefsEditor;
SharedPreferences prefs;
Bitmap[] picss = null;
static int width;
private static int FRIENDS = 0;
private static int PEOPLE = 1;
private static int MAP = 2;
private static int CAMERA = 3;
private static int TOP_TILE = 4;
LinearLayout topTile = null;
LinearLayout mainLayout;
private int NUM_OF_BUTTONS = 4;
ImageButton[] buttonList = null;
Bitmap background;
protected Activity activity;
protected String placeId = null;
protected ViewGroup container;
protected View view;
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
activity = getActivity();
view = getView();
setupObjects(view);
setupLayoutsAndImages(view);
//Populate the UI by initiating the loader to retrieve the
//details of the venue from the underlying Place Content Provider.
if (placeId != null)
getLoaderManager().initLoader(0, null, this);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_screen , container, false);
this.container = container;
return view;
}
public void onDestroyView() {
super.onDestroyView();
Log.d(TAG, "onDestroyView()");
buttonList[FRIENDS].setImageBitmap(null);
buttonList[PEOPLE].setImageBitmap(null);
buttonList[MAP].setImageBitmap(null);
buttonList[CAMERA].setImageBitmap(null);
topTile.setBackground(null);
//Removes all the onClickListeners
buttonList[FRIENDS].setOnClickListener(null);
buttonList[PEOPLE].setOnClickListener(null);
buttonList[MAP].setOnClickListener(null);
buttonList[CAMERA].setOnClickListener(null);
topTile.setOnClickListener(null);
//Sets buttonList and the topTile to null
buttonList = null;
topTile = null;
//Recycles the bitmaps and sets picss to null
if (picss != null) {
picss[FRIENDS].recycle();
picss[PEOPLE].recycle();
picss[MAP].recycle();
picss[CAMERA].recycle();
picss = null;
}
mainLayout.setBackground(null);
background.recycle();
unbindDrawables(view);
view = null;
activity = null;
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
public void onClick(View v) {
Log.d(TAG, "Got within here.");
switch (v.getId()) {
case R.id.b_friendButton:
FragmentTransaction trans = getActivity().getSupportFragmentManager().beginTransaction();
trans.replace(R.id.fragment_container, new FriendsListFrag());
trans.addToBackStack(null);
trans.commit();
break;
case R.id.b_peopleButton:
break;
case R.id.b_mapButton:
break;
case R.id.b_CameraButton:
break;
case R.id.ll_Dynamic_Tile:
break;
}
}
private void setupObjects(View view) {
Log.d(TAG, "Attempting to setupObjects.");
mainLayout = (LinearLayout) view.findViewById(R.id.MainActivity_Main_Layout);
topTile = (LinearLayout) view.findViewById(R.id.ll_Dynamic_Tile);
buttonList = new ImageButton[NUM_OF_BUTTONS];
buttonList[FRIENDS] = (ImageButton) view.findViewById(R.id.b_friendButton);
buttonList[PEOPLE] = (ImageButton) view.findViewById(R.id.b_peopleButton);
buttonList[MAP] = (ImageButton) view.findViewById(R.id.b_mapButton);
buttonList[CAMERA] = (ImageButton) view.findViewById(R.id.b_CameraButton);
picss = new Bitmap[5];
buttonList[FRIENDS].setOnClickListener(this);
buttonList[PEOPLE].setOnClickListener(this);
buttonList[MAP].setOnClickListener(this);
buttonList[CAMERA].setOnClickListener(this);
int width = getActivity().getWindowManager().getDefaultDisplay().getWidth();
int height = getActivity().getWindowManager().getDefaultDisplay().getHeight();
background = GetImage.decodeSampledBitmapFromResource(getResources(),
R.drawable.background2, width, height);
System.out.println(mainLayout == null);
mainLayout.setBackground(new BitmapDrawable(getResources(), background));
}
private void setupLayoutsAndImages(View view) {
Log.d(TAG, "Attempting to setupLayoutsAndImages.");
System.out.println("Width: " + width);
final ImageButton myButton = (ImageButton) getView().findViewById(R.id.b_friendButton);
getView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
System.out.println("Fragwidth: " + getView().getWidth());
System.out.println("FragHeight: " + getView().getHeight());
System.out.println("Button: " + myButton.getWidth());
width = myButton.getWidth();
System.out.println("Width: " + width);
getView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
width, width, 1.0f);
int marg = (int) getResources().getDimension(
R.dimen.main_buttonpadding);
params.setMargins(marg, marg, marg, marg);
//Setting the params for the buttons.
buttonList[FRIENDS].setLayoutParams(params);
buttonList[PEOPLE].setLayoutParams(params);
buttonList[MAP].setLayoutParams(params);
buttonList[CAMERA].setLayoutParams(params);
picss[FRIENDS] = GetImage.decodeSampledBitmapFromResource(
getResources(), R.drawable.tilefriendsmall, width, width);
picss[PEOPLE] = GetImage.decodeSampledBitmapFromResource(
getResources(), R.drawable.tilepeoplesmall, width, width);
picss[MAP] = GetImage.decodeSampledBitmapFromResource(
getResources(), R.drawable.tilemapsmall, width, width);
picss[CAMERA] = GetImage.decodeSampledBitmapFromResource(
getResources(), R.drawable.tilecamerasmall, width, width);
picss[TOP_TILE] = GetImage.decodeSampledBitmapFromResource(
getResources(), R.drawable.tilefriendlong, width, width);
//Setting up the background for the buttons.
buttonList[FRIENDS].setImageBitmap(picss[FRIENDS]);
buttonList[FRIENDS].setAlpha(0.6f);
buttonList[PEOPLE].setImageBitmap(picss[PEOPLE]);
buttonList[PEOPLE].setAlpha(0.6f);
buttonList[MAP].setImageBitmap(picss[MAP]);
buttonList[MAP].setAlpha(0.6f);
buttonList[CAMERA].setImageBitmap(picss[CAMERA]);
buttonList[CAMERA].setAlpha(0.6f);
LinearLayout.LayoutParams topParams = new LinearLayout.LayoutParams(
topTile.getWidth(), width);
topParams.setMargins(marg, marg, marg, marg);
topTile.setLayoutParams(topParams);
topTile.setBackground(new BitmapDrawable(getResources(),
picss[TOP_TILE]));
topTile.setAlpha(0.6f);
}
});
}
Donné le code ci-dessus, lorsque je passe à la FriendsListFrag() je conserve la précédente de la mémoire qui a été allouée pour la MainMenuFragment. J'ai essayé d'utiliser la Mémoire de l'Analyseur, mais ont eu peu de chance avec elle.
OriginalL'auteur Jake Alsemgeest | 2013-11-16
Vous devez vous connecter pour publier un commentaire.
Vous de continuer de créer (et de les attacher), une nouvelle instance de votre fragment.
Changer cela:
À quelque chose comme:
La FragmentManager conserve les références des Fragments et des poignées que par lui-même. Vous pouvez les supprimer si vous le souhaitez (avant l'appel de l'appel à onSaveInstance()) à l'aide de .detach() la méthode dans le FragmentManager.
Que vous pouvez faire:
Remarque: C'est tous les pseudo-code et je n'ai pas le tester, il y a peut être des fautes de frappe, mais vous obtenez l'idée
J'ai essayé ta suggestion et il semble que je suis encore en utilisant la même quantité de mémoire. Il commence à 10023 et des sauts jusqu'à 18123 lors de la commutation des fragments... qui n'a pas beaucoup de sens, puisque le second n'ont pas autant en termes d'objets et d'images.
Bien maintenant que vous avez les Fragments de traités correctement. La prochaine étape pourrait être d'optimiser le chargement de bitmap. Vous pourriez essayer de Picasso (bibliothèque) que, depuis que il va gérer le bitmap du cycle de vie et assurez-vous que vous n'avez pas une fuite de mémoire.
Ok, ça sonne bien. J'ai regardé le Picasso de la bibliothèque. Cela fonctionne correctement dans des fragments?
Oui, c'est fait. C'est écrit et maintenu par la même personne qui a écrit SherlockLibrary entre autres connu Android libs. (Ou au moins, il fonctionne sur elle).
OriginalL'auteur Martin Marconcini
C'est probablement votre OnGlobalLayout auditeur. J'ai le même problème que c'est en quelque sorte fuites le fragment, même si j'non dans onDestroy et mis à null.
Essayer le fragment sans la mise en œuvre de l'auditeur et de vérifier si la fuite est toujours présente.
Toutefois, malheureusement, je ne pouvais pas trouver une solution de contournement ou de remplacement pour...
OriginalL'auteur marcel12345689