J'ai souvent besoin d'accéder à des méthodes qui nécessitent un référencement d'activité. Par exemple, pour utiliser getWindowManager
, je dois accéder à une activité. Mais souvent, mon code pour utiliser ces méthodes est dans une autre classe qui ne fait pas référence à une activité. Jusqu'à présent, j'ai stocké une référence à l'activité principale ou transmis le contexte d'une activité à la classe. Y a-t-il une meilleure façon de faire cela?
Si vous avez déjà un contexte valide, utilisez simplement ceci: Activity activity = (Activity) context;
Le contexte de passage est un meilleur moyen d’activité de référence.
Vous pouvez passer le contexte à une autre classe.
IN Activité ::
AnotherClass Obj = new AnotherClass(this);
DANS une autre classe
class AnotherClass{
public AnotherClass(Context Context){
}
}
Vous pouvez implémenter les méthodes nécessaires dans votre activité et implémenter un Handler . Ensuite, passez simplement une instance de gestionnaire à vos classes, où vous pourrez obtenir un message pour le gestionnaire et l'envoyer à la cible.
J'ai trouvé un moyen d'obtenir l'activité dans un cours autre que l'activité que je n'ai pas vu discuter dans les forums. C'était après de nombreuses tentatives infructueuses d'utilisation de getApplicationContext () et de passage du contexte en tant que paramètre aux constructeurs, aucun d'entre eux n'ayant donné d'activité. J'ai vu que mes adaptateurs transmettaient le contexte entrant à Activity. J'ai donc effectué le même transtypage vers mes constructeurs de classe de non-activité:
public class HandleDropdown extends Application{
...
public Activity activity;
...
public HandleDropdown() {
super();
}
public HandleDropdown(Activity context) {
this.activity = context;
this.context = context;
}
public void DropList(View v,Activity context) {
this.activity = context;
this.context = context;
...
}
Après cette conversion de conversion du contexte en activité, je pouvais utiliser this.activity lorsque j'avais besoin d'un contexte d'activité.
Vous pouvez faire de votre instance d'application un singleton et l'utiliser lorsque vous avez besoin d'un contexte.
Un exemple est dans cette question:
Application Android en tant que Singleton
De cette façon, lorsque vous avez besoin d’un contexte, vous pouvez l’obtenir avecContext context = MyApplication.getInstance()
Ce n'est peut-être pas la solution la plus propre, mais cela a bien fonctionné pour moi jusqu'à présent.
Il y a beaucoup de façons de communiquer avec les activités.
vous pouvez utiliser:
la méthode startActivityForResult
un système de message diffusé et de récepteur (vous pouvez diffuser un événement de l'activité réelle et enregistrer un récepteur dans l'activité cible. N'oubliez pas que l'activité cible doit être préalablement initialisée et non terminée)
Nous avons construit un cadre pour cela. Nous avons une classe BaseActivity
qui hérite de Activity
. Elle remplace toutes les méthodes de cycle de vie et contient des variables statiques (de classe) qui assurent le suivi de la pile d'activités. Si quelque chose veut savoir quelle est l'activité en cours, il appelle simplement une méthode statique dans BaseActivity
qui renvoie l'activité au-dessus de notre pile gérée de manière privée.
C'est un peu hacky, mais ça marche. Je ne suis pas sûr de le recommander cependant.
Je suis nouveau sur Android, ma suggestion peut donc sembler loufoque, mais que se passe-t-il si vous créez simplement une référence à votre activité en tant que propriété privée et l'attribuez dans la méthode OnCreate? Vous pouvez même créer votre CustomActivity avec OnCreate de la sorte et dériver toutes vos activités de votre CustomActivity, et non de l'activité générique fournie par adnroid.
class blah extends Activity{
private Activity activityReference;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityReference = this;
}
}
Intent i = new Intent(activityReference, SomeOtherActivity.class)
etc
Gérez l’intention dans la classe dans laquelle vous voulez utiliser ces méthodes et envoyez-lui vos informations dans un paquet comme ceci:
Intent i = new Intent("Android.intent.action.MAIN");
i.setComponent(new ComponentName("com.my.pkg","com.my.pkg.myActivity"));
Bundle data = new Bundle();
i.putExtras(data);
startActivityForResult(i);
Ensuite, utilisez OnActivityResultListener pour récupérer les nouvelles données.
public static Activity getLaunchActivity()
{
final Class<?> activityThreadClass = Class.forName("Android.app.ActivityThread");
final Method methodApp = activityThreadClass.getMethod("currentApplication");
App = (Application) methodApp.invoke(null, (Object[]) null);
Intent launcherIntent = App.getPackageManager().getLaunchIntentForPackage(App.getPackageName());
launchActivityInfo = launcherIntent.resolveActivityInfo(App.getPackageManager(), 0);
Class<?> clazz;
try
{
clazz = Class.forName(launchActivityInfo.name);
if(clazz != null)
return Activity.class.cast(clazz.newInstance());
}
catch (Exception e)
{}
return null;
}
J'ai résolu ce problème en faisant qu'une classe singleton ait une instance de la classe ci-dessous en tant que membre.
public class InterActivityReferrer <T> {
HashMap<Integer, T> map;
ArrayList<Integer> reserve;
public InterActivityReferrer() {
map = new HashMap<>();
reserve = new ArrayList<>();
}
public synchronized int attach(T obj) {
int id;
if (reserve.isEmpty()) {
id = reserve.size();
}
else {
id = reserve.remove(reserve.size() - 1);
}
map.put(id, obj);
return id;
}
public synchronized T get(int id) {
return map.get(id);
}
public synchronized T detach(int id) {
T obj = map.remove(id);
if (obj != null) reserve.add(id);
return obj;
}
}
Cette classe peut obtenir un objet T et renvoyer un entier unique attribué à l'objet par attach (). Les entiers assignés n'entreront pas en conflit sauf en cas d'échec de HashMap. Chaque entier affecté sera libéré lorsque l'objet correspondant sera détaché par detach (). Les entiers libres seront réutilisés lorsqu'un nouvel objet est attaché.
Et à partir d'une classe singleton:
public class SomeSingleton {
...
private InterActivityReferrer<Activity> referrer = new InterActivityReferrer<>();
...
public InterActivityReferrer<Activity> getReferrer() {return referrer;}
}
Et d'une activité qui doit être référée:
...
int activityID = SomeSingleton.getInstance().getReferrer().attach(this);
...
Maintenant, avec cela, un entier unique correspondant à cette instance d'activité est renvoyé. Et un entier peut être fourni dans une autre activité de départ en utilisant Intent et putExtra ().
...
Intent i = new Intent(this, AnotherActivity.class);
i.putExtra("thisActivityID", activityID);
startActivityForResult(i, SOME_INTEGER);
...
Et de l'autre activité:
...
id refereeID = getIntent().getIntExtra("thisActivityID", -1);
Activity referredActivity = SomeSingleton.getInstance().getReferrer().get(refereeID);
...
Et enfin l'activité peut être référée. Et InterActivityReferrer peut être utilisé pour toute autre classe.
J'espère que ça aide.