7
votes

Android App perdant des données pendant le changement d'orientation

J'ai une application que j'ai copiée à partir d'un didacticiel qui capture une image avec mediastore.action_image_capture . J'ai une sorte d'étrangeté sur laquelle je dirige l'application sur mon téléphone.

L'application de la caméra elle-même retourne son orientation à quelques reprises pendant l'opération, même si je ne bouge pas le téléphone. Il passe brièvement en mode paysage avant de retourner à l'application de tutoriel. Par conséquent, l'application de tutoriel retourne en mode portrait après le contrôle de contrôle et l'image est perdue. J'ai essayé de définir l'orientation de l'activité de la caméra au paysage et que l'image n'est pas perdue.

mais la mise en page de l'application est destinée au mode portrait. Ou, si je tiens ma caméra dans l'orientation de paysage tout en capturant la photo, je peux éteindre le téléphone après que mon application soit revenue à la concentration et ne perdez pas l'image.

J'ai fait des piquer sur le Web. Quelqu'un sur Stackoverflow a mentionné que le changement d'orientation a entraîné des appels supplémentaires à Oncreate . "La raison pour laquelle Oncreate () est appelé est parce que lorsque vous appelez l'activité de la caméra pendant l'orientation portrait, elle changera l'orientation et détruisez votre activité précédente." J'ai exécuté l'application en mode de débogage avec des points d'arrêt définis sur Oncreate et dans les méthodes OnAstiVIVIVIVIVITURE . Il est en effet vrai que oncreate est appelé quand je prends la photo en mode portrait. L'ordre des appels est surCréate, OnActivityResult, Oncreate. Si je prends la photo en mode paysage (qui est l'endroit où mon application de la caméra se termine dans les deux sens), Oncreate ne s'appelle pas. Maintenant que j'ai une idée de ce qui se passe, comment puis-je garder cela d'être un problème? Voici ce que l'application ressemble maintenant à: xxx

et voici ce que j'ai dans le manifeste pour cette activité: xxx

J'ai fait des recherches considérables, mais une grande partie de ce que je trouve manque d'exemples concrets. J'ai besoin de savoir à quoi ressemble le code, pas seulement de la fonctionnalité à utiliser.

Mon téléphone est un mouvement LG. Quelqu'un d'autre a-t-il rencontré ce problème? Comment peut-il être corrigé?


0 commentaires

7 Réponses :


1
votes

4 commentaires

OnsaveInstancestate ne peut pas enregistrer bitmaps


@Budius oui il peut - ride.blogspot.com/2010/08/...


Bien que votre lien ne fonctionne pas, après mon commentaire, j'ai remarqué que j'avais tort, je m'excuse pour cela, et je serais heureux de vous déstabiliser, mais je ne peux pas si vous ne modifiez votre réponse. Mais j'insiste que, bien que les bitmaps soient conventionnés, il n'est pas conseillé de l'utiliser pendant la sauvegarde de l'enseignement, car il prend du temps et de la mémoire pour compléter de telles transactions et pourra rendre la rotation très longeante.


Dépend du bitmap - s'il est petit, ce n'est peut-être pas un problème. De plus, pour la rotation, le processus n'est pas tué et que les objets de l'intention ne doivent pas réellement être colisés, il ne devrait pas simplement conserver une référence.



1
votes

Avez-vous essayé d'ajouter Android: LaunleMode = "SingleTop" à l'activité dans Android Menifest, a travaillé pour moi. Le problème est que Android redémarre l'activité lorsque les modifications d'orientation et vos données sont perdues, si votre activité est déjà exécutée, il ne crée pas une nouvelle instance.

        <activity 
            android:name=".FacebookActivity" 
            android:label="@string/facebook_app_name"
            android:launchMode="singleTop"
            android:configChanges="keyboardHidden|orientation"
            >
        </activity>


1 commentaires

Merci. Juste pour les sources, j'ai essayé cela, mais cela ne change pas le comportement de mon application.



0
votes

Utilisez le OnsaveInstancestate et ensuite l'argument que vous obtenez via Oncreate ou sur le manifeste que vous géreriez les changements d'orientation en utilisant configchange et réglage sur quels cas vous souhaitez gérer vous-même (par exemple orientation | Screensize | ScreenLayout).


8 commentaires

OnsaveInstancestate ne peut pas enregistrer bitmaps


Ok, je suis confus sur le problème. Pouvez-vous s'il vous plaît expliquer d'autres choses à ce sujet? Vous avez également essayé également de définir les configchanges?


Je ne suis pas celui qui a posé la question. Je vous explique simplement que vous le suggérez d'utiliser OnsaveDInstancestate mais les bitmaps ne sont pas conventionnels, par conséquent, ne peuvent donc pas être sauvés avec ONSAVEDInstanCetate.


Donc, il peut l'enregistrer dans son dossier de stockage interne / externe. Je ne comprends toujours pas la question cependant.


Oui. J'ai des configuches dans mon manifeste comme indiqué ci-dessus. J'ai aussi une substitution sur OneConfigurationChanged. Le problème principal est que les applications sur mon téléphone perdent les données de leurs points de vue lorsque le téléphone est tourné. Le programme fonctionne simplement bien dans l'émulateur. Donc, quelque chose doit être fait pour enregistrer explicitement les données de vue.


Mais vous avez appelé SetContentView () et initialiser () dans le contournement unconfigurationChanged ... veuillez les supprimer afin qu'ils ne réinitialent pas tout. De cette façon, ils devraient avoir le même contenu qu'avant. En outre, veuillez définir tous les indicateurs des configuches que j'ai écrites et supprimer l'orientation depuis que vous souhaitez gérer les modes de paysage et de portrait.


Et pourquoi les gens continuent de bownvot sans dire pourquoi? S'il vous plaît avoir la dignité pour écrire pourquoi nous essayons tous de nous aider. Si je me trompe, je peux corriger la réponse ou même la supprimer, mais pourquoi la bowevote?


@Budius Mais vous n'avez pas considéré l'autre solution, et vous n'avez pas considéré cela avant OnsaveInstancestate, vous pouvez enregistrer le bitmap dans un fichier. Vous venez de descendre sans me laisser expliquer ce que vous pouvez faire.



8
votes

Vous devrez remplacer ONretAnnonConfigurationInstance a> et utiliser GetLastnonConfigurationInstance pour enregistrer / restaurer le bitmap.

comme ceci: p> xxx pré>

puis sur votre activité u remplaçable: p> xxx pré>

qui va " Enregistrer "le bitmap pendant la rotation. p>

EDIT: strong> p>

Exemple Utilisation de OnsaveInstanCetate suggérée qui fonctionnera Mais n'est pas conseillé car il utilisera beaucoup de mémoire et être très lent mais vous aurez besoin d'autres situations bientôt: p>

// This fragment will be managed by the framework but we won't built a UI for it.
public class FragRetained extends Fragment{
   public static final String TAG = "TAG.FragRetained";
   private Bitmap bitmap;

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

        // Tell the framework to try to keep this fragment around
        // during a configuration change.
        setRetainInstance(true);
    }
    public Bitmap getBitmap() { return bitmap; }
    public void setBitmap(Bitmap bmp) { bitmap = bmp; }
}

public class MyActivity extends Activity{

    private FragRetained myFragRetained;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
            // set the content view
            img = (ImageView)findViewById(R.id.byImgV);


            myFragRetained = getFragmentManger.findFragmentByTag(FragRetained.TAG);
            if(myFragRetained == null){
                myFragRetained = new FragRetained ();
            }else{
               Bitmap b = myFragRetained.getBitmap();
               if(b==null){
                  // the user still did not choose the photo
               }else{
                  img.setImageBitmap(b);
               }
            }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            bmp = (Bitmap)extras.get("data");
            iv.setImageBitmap(bmp);
            myFragRetained.setBitmap(bmp);
        }
    }

}


7 commentaires

Apparemment, onretainnonconfigurationInstance est obsolète. La documentation suggère à l'aide de l'API de fragment SetTainStance (Boolean) à la place. Est-ce que quelqu'un sait comment utiliser cela?


C'est en effet mais rien ne vous empêche d'utiliser maintenant que vous apprenez toujours. Pour utiliser la version de fragment, vous auriez un fragment sans UI qui demanderait à conserver l'instance de SEDRETAREINSTINSTANCE (VRAI) pendant ONCREATE () et vous pouvez créer des méthodes de getBitmap () de SETBITMAP (). Donc, après vous avoir obtenu l'image, vous pouvez installer le fragment et setbitmap (). Après la rotation (pendant l'activité Oncreee ()), vous pouvez obtenir le fragment avec GetFragmentManager (). FINDFRAGMENTBYTAG (String) et appelez GetBitmap () dessus. Mais je pense juste que c'est trop pour quelqu'un qui vient d'apprendre la plate-forme.


Apparemment ( Stackoverflow.com/a/7677326/906362 ) Il existe un exemple en utilisant un fragment moins utile + SeretainStance () sur le Exemples que vous avez téléchargés avec le SDK, FragmentReTainInstancesUnupport ou quelque chose comme ça.


Ok, peut-être que je suis nouveau à Android et à Java, mais je suis programmée depuis 1980. Si j'en ai un bon exemple, je suis plutôt bon pour ramasser ce qui est nécessaire. Mais quand il n'y a pas d'exemples, la documentation a tendance à ressembler à Gobbledygook pour moi. Cela a été mon problème pour essayer de comprendre cela. Les gens disent à utiliser OnsaveInstancestate et similaires, mais je n'ai pas trouvé d'exemple de comment utiliser OnsaveInstancestate n'importe où que j'ai regardé. La documentation Android manque cruellement dans des exemples.


Je ne voulais pas être condescendant mais que vous n'avez qu'une réputation et je pouvais voir que vous commencez à partir d'Android, donc j'ai essayé de simplifier. Mais de toute façon, je vais éditer ma réponse avec les deux exemples sur la manière d'utiliser OnSaveInstancestate (selon mes commentaires qui ne fonctionnera pas sur votre SIAUTATION, mais seront probablement utiles dans un avenir proche) et pour la SetRetainStance (). S'il vous plaît vérifier à nouveau.


Comment cela n'a-t-il pas eu +1? Pas un programmateur Android ici, mais bon effort (ping @roxann).


+1 pour corriger la réponse en utilisant la méthode avant de modifier;) J'espère que la réponse est acceptée un jour



3
votes

Je suis allé à une réunion du groupe de développement mobile lundi et a eu un indice. Un programmeur qui écrit des applications pour une variété de plates-formes pour une grande entreprise a suggéré de joindre le bitmap à l'objet d'application. En regardant comment je pourrais faire cela, j'ai finalement proposé une solution qui fonctionne (nouvelle question à la fin du poste) sur la base de suggestions dans le blog suivant: http://android-er.blogspot.com /2011/10/Share-Bitmap-between-Activités-As.html

Fondamentalement, cela impliquait la configuration du bitmap comme une ressource commune dans un endroit où toute activité de l'application peut y accéder. J'ai créé une nouvelle classe comme suit: P>

@Override
protected void onPause() {
        // TODO Auto-generated method stub
              super.onPause();
        if (isFinishing()) {
                   // Save the bitmap.
                        CommonResources.cameraBmp = null;
           }
}


0 commentaires

1
votes

Après avoir cherché sur le Web un peu de temps pour une solution simple, j'ai regardé un code et je suis venu avec ceci, j'espère que cela aide toute personne qui considère ce fil à l'avenir!

J'ai une variable globale URI imageuri = null; dans ma classe d'activité, qui est utilisé pour définir l'URI de l'image de l'IMAVEVoir que j'utilise; et le code suivant dans oncreate () et onsaveInstansetate () xxx

J'espère que quelqu'un trouvera cette question utile - Si vous voulez plus de détails.


0 commentaires

15
votes

Dans le manifeste, dans chaque activité, j'utilise des configchanges: xxx

J'espère que cela vous aident.


1 commentaires

Veuillez noter que le drapeau orientation est le plus important de la réponse et enregistré ma journée ...