47 votes

Meilleures pratiques de programmation asynchrone

Récemment, j'ai écrit ma première application Android qui était d'environ 8 000 à 10 000 lignes de code. Une chose qui ne cesse entravé mon usage normal des design patterns android est l'utilisation intensive des appels asynchrones (ouverture des boîtes de dialogue, les activités, etc). Pour cette raison, mon code très rapidement commencé à chercher des "spaghetti", et finalement, j'ai commencé à détester la recherche à certaines classes.

Sont-t-il des modèles de conception ou de programmation des méthodes pour les systèmes tels que quiconque puisse recommander? Avez-vous des suggestions pour la rédaction gérable code asynchrone?

46voto

Wroclai Points 15042
  • Utiliser des variables globales

Si vous ne voulez pas gâcher votre code avec un simple Intent.putExtra() des appels et de gérer ce genre de choses uniques à chaque Activity vous aurez à utiliser des variables globales au sein de l'application. Étendre Application et de stocker des données que vous avez besoin aussi longtemps que votre application est en vie. Pour la mise en œuvre, l'utilisation de cette excellente réponse. Cela rendra les dépendances entre les activités de disparaître. Par exemple, disons que vous avez besoin d'un "nom d'utilisateur" pour votre application lors de l'application du cycle de vie - c'est un excellent outil pour cela. Pas besoin de sale Intent.putExtra() des appels.

  • Utiliser les styles

Une erreur courante lors de la prise de la première application Android, c'est que c'est une habitude de commencer à écrire les vues XML. Les fichiers XML (sans problème et très rapide), aller jusqu'à de très nombreuses lignes de code. Ici vous pouvez avoir une solution où il vous suffit d'utiliser l' style de l'attribut pour implémenter un comportement spécifique. Considérons par exemple ce morceau de code:

values/styles.xml:

<style name="TitleText">
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:textSize">18sp</item>
    <item name="android:textColor">#000</item>
    <item name="android:textStyle">bold</item>   
</style>

layout/main.xml:

Maintenant, si vous avez, disons, deux TextViews et tous les deux doivent avoir le même comportement, à leur faire utiliser l' TitleText style. Exemple de code:

<!--- ... -->
<TextView
   android:id="@+id/textview_one"
   style="@style/TitleText" 
/>

<TextView
   android:id="@+id/textview_two" 
   style="@style/TitleText" 
/>
<!--- ... -->

Simple et vous n'avez pas besoin de dupliquer le code. Si vous voulez vraiment chercher plus loin sur ce sujet, veuillez jeter un oeil à la Disposition des Astuces: Création d'Réutilisables Composants de l'INTERFACE utilisateur.

  • Utiliser des chaînes de

Ce point est courte, mais je pense que c'est important de le mentionner. Une autre erreur que les développeurs peuvent faire est de l'ignorer strings.xml et il suffit d'écrire l'INTERFACE utilisateur messages (et les noms d'attribut) à l'intérieur du code (où il en aura besoin). Pour rendre votre application plus facile à maintenir; il suffit de définir les messages et les attributs dans le strings.xml fichier.

  • Créer et utiliser un outil global de la classe

Quand j'ai écrit ma première application que je viens d'écrire (et dupliqué) méthodes où j'en avais besoin. Le résultat? Un grand nombre de méthodes qui ont le même comportement entre les différentes activités. Ce que j'ai appris, c'est d'en faire un outil de classe. Par exemple, disons que vous avez à faire des requêtes web dans toutes vos activités. Dans ce cas, ignorez les définissant dans l' Activity et de faire une méthode statique. Exemple de code:

public final class Tools {

    private Tools() {
    }

    public static final void sendData(String url, 
              String user, String pass) {
        // URLConnections, HttpClients, etc...
    }

}

Maintenant, vous pouvez simplement utiliser ce code ci-dessous dans votre Activity qui a besoin d'envoyer des données vers un serveur:

Tools.sendData("www.www.www", "user", "pass");

Toutefois, vous obtenez le point. L'utilisation de ce "modèle" où vous en avez besoin, il va vous empêcher de perturber le fonctionnement de votre code.

  • Laissez classes personnalisées définir le comportement où l'utilisateur doit interagir avec votre application

C'est probablement le plus utile. Pour définir simplement "où l'utilisateur doit interagir avec votre application" disons que vous avez un Menu, dont le comportement est très long en termes de lignes, pourquoi continuons-nous à l' Menu'des calculs dans la même classe? Chaque petit élément fera de votre Activity de la classe d'un douloureux morceau de code plus votre code "spaghetti". Par exemple, au lieu d'avoir quelque chose comme ceci:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    MenuItem item;
    item = menu.findItem(R.id.menu_id_one);
    if (aBooleanVariable) {
        item.setEnabled(true);
    } else {
        item.setEnabled(false);
    }
    // More code...
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem i) {
    // Code, calculations...
    // ...
    // ...
    return super.onOptionsItemSelected(i);
}

refaire quelque chose comme ceci:

private MyCustomMenuInstance mMenuInstance;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);        
    setContentView(R.layout.main);

    mMenuInstance = new MyCustomMenuInstance();
}  

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    mMenuInstance.onPrepareOptionsMenu(menu);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem i) {
    mMenuInstance.onOptionsItemSelected(i);
    return super.onOptionsItemSelected(i);
}

Par exemple, MyCustomMenuInstance:

public class MyCustomMenuInstance { 

    // Member fields..

    public MyCustomMenuInstance() {
        // Init stuff.
    }

    public void onPrepareOptionsMenu(Menu menu) {
        // Do things..
        // Maybe you want to modify a variable in the Activity 
        // class? Well, pass an instance as an argument and create
        // a method for it in your Activity class.
    }

    public void onOptionsItemSelected(MenuItem i) {
        // Do things..
        // Maybe you want to modify a variable in the Activity 
        // class? Well, pass an instance as an argument and create
        // a method for it in your Activity class.
    }

}

Vous voyez où cela va. Vous pouvez l'appliquer à beaucoup de choses, par exemple, onClick, onClickListener, onCreateOptionsMenu, la liste est longue. Pour en savoir plus "les meilleures pratiques", vous pouvez voir quelques exemples d'applications à partir de Google ici. Comparer la façon dont ils ont mis en œuvre les choses dans une belle et bonne façon.

Dernier mot; garder votre code propre, le nom de vos variables et de méthodes d'une manière logique et surtout une façon correcte. Toujours, toujours à comprendre où vous en êtes dans votre code, c'est très important.

6voto

Aleadam Points 25433

À partir d'un amateur de point de vue, je n'attends pas de ma première tentative d'être propre, prêt à la production de l'app. Je me retrouve avec des spaghetti, fettucini et même des raviolis code parfois. À ce moment, j'essaie de repenser à ce qui est ce que je déteste le plus dans le code, et la recherche d'une meilleure alternative:

  • Repenser vos classes afin de mieux décrire vos objets,
  • garder le code de chaque méthode à un minimum,
  • d'éviter les dépendances de variables statiques n'importe où vous le pouvez,
  • utiliser des threads pour une tâche coûteuse, ne les utilisez pas pour rapide des procédures,
  • séparer l'INTERFACE utilisateur de l'application de la logique (gardez-le dans vos classes à la place),
  • garder privé des champs où vous le pouvez: il sera utile lorsque vous souhaitez modifier votre classe,
  • parcourir ces jusqu'à ce que le code

L'une des erreurs les plus communes que j'ai vu dans les méthodes asynchrones est d'utiliser une variable statique à l'intérieur d'une boucle qui crée un ou plusieurs threads, sans pour autant considérer que la valeur peut changer dans un autre thread. Éviter la statique!

Comme OceanBlue points, il peut ne pas être clair à partir de ce qu' final static variables de ne pas créer de danger, mais les variables statiques qui peuvent changer. Il n'est pas un problème avec la statique eux-mêmes, mais avec l'idée qu'ils ont une valeur, et puis de trouver que la valeur a changé. Il peut être difficile de repérer où était le problème. Des exemples typiques serait un compteur de clics ou d'une valeur de minuterie, quand il pourrait y avoir plus d'une vue cliqué ou plus d'une minuterie.

J'espère que vous recevrez des suggestions des personnes avec beaucoup plus d'expérience que moi. Bonne chance!

3voto

jefflunt Points 20244

Si la manipulation de l'INTERFACE utilisateur est votre plus grande préoccupation, alors vous aurez envie de maître event-driven de codage. L'idée de l'event-driven de codage sont derrière toute moderne, l'INTERFACE utilisateur des systèmes, et sont utiles dans toutes sortes de choses (et pas seulement de l'INTERFACE utilisateur).

Le moyen le plus facile pour moi d'y penser lors de l'apprentissage était simplement de traiter chaque composante et de l'événement comme si c'est l'auto-contenue. Tout ce que vous devez vous soucier est l'objet de l'événement est passé dans votre cas de la méthode. Si vous êtes habitué à l'écriture d'applications qui s'exécutent essentiellement à partir de début à la fin, c'est un peu d'un changement de mentalité, mais avec la pratique, vous y arriverez très vite.

0voto

cibercitizen1 Points 3093

Qu'en est-il de l'utilisation du modèle Model View Controller?

Au moins, vous devez isoler dans le "modèle" (objet ou ensemble d'objets) tout l'état et sa gestion logique, et avoir dans une classe séparée (peut-être la classe Activity) tout ce qui concerne les vues, les écouteurs, les rappels, ...)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X