J'ai une interface comme celle-ci:
public interface MyInterface {
public void aMethod();
}
Mon objet personnalisé:
public class MyObject {
private Context context;
private MyInterface inter;
public MyObject(Context context) {
this.context = context;
this.inter = (MyInterface) this.context;
inter.aMethod();
}
}
Activité principale:
public class MainActivity extends Activity implements MyInterface {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyObject my = new MyObject(this);
}
@Override
public void aMethod() {
Toast.makeText(this, "done", Toast.LENGTH_SHORT).show();
}
}
Ici, à l'intérieur du constructeur MyObject, je peux obtenir l'interface à partir du contexte, puis communiquer avec l'activité.
Mais comment envoyer une interface d'une activité à une autre?
J'ai besoin d'appeler une méthode dans Activity1 depuis Activity2
Existe-t-il un moyen comme celui-ci?
Remarque: je ne veux pas utiliser de fragment.
D'abord et avant tout, c'est très mauvais:
this.inter = (MyInterface) this.context;
Si vous passez un contexte dans le constructeur qui n'implémente pas votre interface, votre application plantera et il est facile de commettre une telle erreur. Donc, vous voyez, c'est très sujet aux erreurs, implémentez-le plutôt comme ceci:
public class MyObject {
private Context context;
private MyInterface inter;
public MyObject(Context context, MyInterface inter) {
this.context = context;
this.inter = inter;
inter.aMethod();
}
}
De cette façon, c'est beaucoup plus sûr et plus propre.
Pour envoyer le Object
à un autre Activity
assurez-vous qu'il implémente Serializable
comme ceci:
public interface MyInterface extends Serializable {
public void aMethod();
}
Et maintenant, vous pouvez simplement ajouter l'interface en supplément au Intent
qui démarre l'autre Activity
:
Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra("interface", inter);
startActivity(intent);
Et dans le OtherActivity
vous pouvez obtenir le Object
du Intent
comme ceci:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
MyInterface inter = (MyInterface) intent.getSerializableExtra("interface");
...
}
Lorsque vous faites quelque chose comme ça dans votre Activity
vous créez une classe anonyme:
OnCreateListener inter = new OnCreateListener() {
@Override
public void onObjCreate() {
Log.d("pltk", "dfgbfdgh");
}
};
Le problème avec une telle classe anonyme est qu'elle n'est pas statique, ce qui signifie que vous pouvez toujours accéder aux méthodes et aux variables de la classe dans laquelle cet écouteur est imbriqué. En interne, la raison en est que cette nouvelle classe conserve une référence à l'instance de la classe qui l'a créée, dans votre cas le Activity
englobant. C'est une bonne chose et nous l'utilisons tout le temps pour OnClickListener
etc. Mais dans votre cas, c'est un problème parce que vous voulez envoyer ce Object
à un autre Activity
. La référence interne à l'ancien Activity
l'empêche d'être sérialisé et c'est une bonne chose. Si vous pouviez simplement envoyer un Object
comme ça, vous créeriez des fuites de mémoire comme un fou à cause de toutes les anciennes références que le garbage collector ne peut pas collecter.
La solution est assez simple, vous pouvez soit définir la classe dans son propre fichier, soit rendre la classe statique. Statique dans ce contexte signifie que la classe est essentiellement traitée comme dans son propre fichier séparé et ne peut donc pas accéder à l'instance de la classe englobante.
Donc, pour résumer ce que vous avez à faire, vous devez soit garder la classe imbriquée et la définir comme suit:
public class YourActivity extends Activity {
private static class OnCreateListenerImpl implements OnCreateListener {
@Override
public void onObjCreate() {
Log.d("pltk", "dfgbfdgh");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_palatok);
OnCreateListener inter = new OnCreateListenerImpl();
Intent in = new Intent(Palatok.this, SecondActivity.class);
in.putExtra("ob", inter);
startActivity(in);
}
}
Ou vous pouvez déplacer l'implémentation dans son propre fichier séparé:
public class OnCreateListenerImpl implements OnCreateListener {
@Override
public void onObjCreate() {
Log.d("pltk", "dfgbfdgh");
}
}
Bien que la raison pour laquelle vous souhaitiez envoyer un OnCreateListener
à un autre Activity
m'échappe encore, cela devrait résoudre votre problème.
J'espère que je pourrais vous aider et si vous avez d'autres questions, n'hésitez pas à demander!
C'est possible, mais ce type d'interraction d'activité <-> activité entraînera des fuites de mémoire. Vous devez utiliser LocalBroadcastManager ( http://developer.Android.com/reference/Android/support/v4/content/LocalBroadcastManager.html ) à la place.