Comment référencer l’activité actuelle ou principale d’une autre classe

J’ai souvent besoin d’accéder à des méthodes qui nécessitent de référencer une activité. Par exemple, pour utiliser getWindowManager , je dois accéder à certaines activités. Mais souvent, mon code d’utilisation de ces méthodes se trouve dans une autre classe sans référence à une activité. Jusqu’à présent, j’ai soit stocké une référence à l’activité principale, soit transmis le contexte d’une activité à la classe. Y a-t-il un meilleur moyen de le faire?

Si vous avez déjà un contexte valide, utilisez simplement ceci: Activity activity = (Activity) context;

Le contexte de passage est préférable pour l’activité de réfraction.

Vous pouvez transmettre le contexte à une autre classe.

Activité IN ::

 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 gestionnaire . Ensuite, passez simplement une instance de gestionnaire à vos classes, où vous pouvez obtenir un message pour le gestionnaire et l’envoyer à la cible.

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 comme Singleton

De cette façon, lorsque vous avez besoin d’un contexte, vous pouvez l’obtenir avec
Context context = MyApplication.getInstance()

Ce n’est peut-être pas la solution la plus propre, mais cela a bien fonctionné jusqu’à présent.

J’ai trouvé un moyen de faire l’activité dans un cours sans activité que je n’ai pas vu discuté dans les forums. C’était après de nombreuses tentatives infructueuses d’utiliser getApplicationContext () et de transmettre le contexte en tant que paramètre aux constructeurs, dont aucun ne donnait d’activité. J’ai vu que mes adaptateurs transmettaient le contexte entrant à Activity. J’ai donc fait la même conversion avec mes constructeurs de classes non actives:

 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 avoir fait cette conversion de conversion du contexte en activité, je pourrais utiliser this.activity où que j’aie besoin d’un contexte d’activité.

Il existe de nombreuses manières de communiquer avec Activités.

vous pouvez utiliser:

  • la méthode startActivityForResult

  • un système de diffusion de messages et de récepteurs (vous pouvez diffuser un événement à partir 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)

  • comme vous le dites, stockez une référence de l’activité cible où vous en avez besoin.

Nous avons construit un cadre pour cela. Nous avons une classe BaseActivity qui hérite d’ Activity et qui remplace toutes les méthodes de cycle de vie et qui comporte des variables statiques (de classe) qui assurent le suivi de la stack d’activités. Si quelque chose veut savoir quelle est l’activité en cours, elle appelle simplement une méthode statique dans BaseActivity qui renvoie l’activité au-dessus de notre stack à gestion privée.

C’est un peu pirate, mais ça marche. Je ne suis pas sûr de le recommander.

Je suis nouveau sur Android, donc ma suggestion peut sembler complexe mais que faire si vous créez une référence à votre activité en tant que propriété privée et que vous l’assignez dans la méthode OnCreate? Vous pouvez même créer votre CustomActivity avec OnCreate comme ça et dériver toutes vos activités à partir de votre CustomActivity, pas 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; } } 

Manipulez l’intention dans la classe que vous souhaitez utiliser pour ces méthodes et envoyez-la dans un bundle comme suit:

  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 un OnActivityResultListener pour récupérer les nouvelles données.

J’ai résolu ce problème en faisant d’une classe singleton une instance de la classe ci-dessous en tant que membre.

 public class InterActivityReferrer  { HashMap map; ArrayList 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 object T et retourner un entier unique atsortingbué à l’object par attach (). Les entiers atsortingbués n’entrent pas en collision, sauf si HashMap échoue. Chaque entier atsortingbué sera libéré lorsque l’object correspondant est détaché par detach (). Les entiers libérés seront réutilisés lorsqu’un nouvel object est attaché.

Et d’une classe singleton:

 public class SomeSingleton { ... private InterActivityReferrer referrer = new InterActivityReferrer<>(); ... public InterActivityReferrer getReferrer() {return referrer;} } 

Et d’une activité à renvoyer:

  ... int activityID = SomeSingleton.getInstance().getReferrer().attach(this); ... 

Maintenant, avec ceci, un entier unique correspondant à cette instance d’activité est retourné. Et un entier peut être livré 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.

 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; } 

Juste une supposition puisque je ne l’ai pas fait mais cela pourrait fonctionner.

1) Obtenez votre applicationContext en faisant de votre classe d’application Android un singleton.

2) Obtenez votre classe ActivityManager du contexte.

3) Obtenez une liste de RunningTaskInfos en utilisant getRunningTasks () sur le ActivityManager.

4) Obtenez le premier élément RunningTaskInfo de la liste qui devrait être la plus récente tâche lancée.

5) Appelez topActivity sur ce RunningTaskInfo qui doit vous renvoyer l’activité supérieure de la stack d’activités pour cette tâche.

Maintenant, cela semble beaucoup plus de travail que toutes les autres méthodes mentionnées ici, mais vous pouvez probablement encapsuler ceci dans une classe statique et l’appeler quand vous voulez. Il semble que cela puisse être le seul moyen d’obtenir l’activité maximale sur la stack sans append de références aux activités.