Мне часто приходится обращаться к методам, требующим ссылки на некоторые действия. Например, чтобы использовать getWindowManager
, мне нужно получить доступ к некоторым Activity. Но часто мой код для использования этих методов находится в каком-то другом классе, который не имеет ссылки на действие. До сих пор я либо сохранил ссылку на основное действие, либо передал контекст некоторой активности классу. Есть ли лучший способ сделать это?
Как ссылаться на текущую или основную активность из другого класса
Ответ 1
Проходящий контекст - лучший способ для действия Refrence.
Вы можете передать Контекст другому классу.
IN Activity::
AnotherClass Obj = new AnotherClass(this);
В другом классе
class AnotherClass{
public AnotherClass(Context Context){
}
}
Ответ 2
Если у вас уже есть допустимый контекст, просто используйте это:
Activity activity = (Activity) context;
Ответ 3
Вы можете реализовать необходимые методы в своей деятельности и реализовать Handler. Затем просто передайте экземпляр обработчика вашим классам, где вы можете получить сообщение для обработчика и отправить его в цель.
Ответ 4
Вы можете сделать экземпляр приложения одиночным и использовать его, когда вам нужен контекст
Пример в этом вопросе:
Android-приложение как Singleton
Таким образом, когда вам нужен контекст, вы можете получить его с помощью
Context context = MyApplication.getInstance()
Это может быть не самое чистое решение, но оно до сих пор хорошо работало для меня
Ответ 5
Я нашел способ получить Activity в класс без активности, который я не видел в форумах. Это произошло после многочисленных неудачных попыток использования getApplicationContext() и передачи контекста в качестве параметра для конструкторов, ни одна из которых не дала Activity. Я видел, что мои адаптеры вставляли входящий контекст в Activity, поэтому я сделал тот же самый перенос для своих конструкторов класса non-activity:
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;
...
}
После этого преобразования преобразования Context в Activity я мог бы использовать this.activity везде, где мне нужен контекст Activity.
Ответ 6
Существует множество способов обмена информацией о деятельности.
вы можете использовать:
-
метод startActivityForResult
-
система широковещательного сообщения и получателя (вы можете транслировать событие из фактической активности и регистрировать получателя в целевом действии. Помните, что целевая активность должна быть предварительно инициализирована и не завершена)
- как вы говорите, сохраните ссылку на целевую деятельность, где вам нужно.
Ответ 7
Мы построили для этого рамки. У нас есть класс BaseActivity
, который наследует от Activity
и переопределяет все методы жизненного цикла и имеет некоторые статические (классные) переменные, которые отслеживают стек действий. Если что-то хочет знать, что такое текущая активность, он просто вызывает статический метод в BaseActivity
, который возвращает активность поверх нашего конфиденциального стека.
Это своего рода хакерство, но оно работает. Я не уверен, что рекомендовал бы это.
Ответ 8
Обрабатывайте намерение в классе, который вы хотите использовать для этих методов, и отправляйте в него информацию в виде Bundle следующим образом:
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);
Затем используйте функцию OnActivityResultListener для захвата новых данных.
Ответ 9
Я новичок в андроиде, поэтому мое предложение может выглядеть густо, но что, если вы просто создадите ссылку на свою деятельность как частную собственность и назначьте ее в методе OnCreate? Вы даже можете создать свою CustomActivity с OnCreate, как это, и получить все свои действия из своей CustomActivity, а не общей активности, предоставляемой adnroid.
class blah extends Activity{
private Activity activityReference;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityReference = this;
}
}
Ответ 10
Я решил это, создав одноэлементный класс с экземпляром класса ниже в качестве члена.
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;
}
}
Этот класс может получить объект T и вернуть уникальное целое число, присвоенное объекту attach(). Назначенные целые числа не будут сталкиваться друг с другом, если HashMap не сработает. Каждое присваиваемое целое число будет освобождено, когда его соответствующий объект будет отсоединен командой detach(). Целые числа Freed будут использоваться повторно при подключении нового объекта.
И из одноэлементного класса:
public class SomeSingleton {
...
private InterActivityReferrer<Activity> referrer = new InterActivityReferrer<>();
...
public InterActivityReferrer<Activity> getReferrer() {return referrer;}
}
И из действия, которое необходимо передать:
...
int activityID = SomeSingleton.getInstance().getReferrer().attach(this);
...
Теперь с этим возвращается уникальное целое число, соответствующее этому экземпляру активности. И целое число может быть доставлено в другую начальную активность с помощью Intent и putExtra().
...
Intent i = new Intent(this, AnotherActivity.class);
i.putExtra("thisActivityID", activityID);
startActivityForResult(i, SOME_INTEGER);
...
И из другого действия:
...
id refereeID = getIntent().getIntExtra("thisActivityID", -1);
Activity referredActivity = SomeSingleton.getInstance().getReferrer().get(refereeID);
...
И, наконец, деятельность может быть передана. И InterActivityReferrer может использоваться для любого другого класса.
Надеюсь, это поможет.
Ответ 11
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;
}
Ответ 12
Просто догадаться, так как я этого не делал, но это может сработать.
1) Получите ваш applicationContext, создав класс Android Application Singleton.
2) Получите класс ActivityManager из контекста.
3) Получите список RunningTaskInfos, используя getRunningTasks() в ActivityManager.
4) Получите первый элемент RunningTaskInfo из списка, который должен быть запущен самой последней задачей.
5) Вызовите topActivity на этом RunningTaskInfo, который должен вернуть вам верхнюю активность в стеке действий для этой задачи.
Теперь это похоже на LOT больше работы, чем на любой из других методов, упомянутых здесь, но вы, вероятно, можете инкапсулировать это в статический класс и просто называть его всякий раз. Кажется, что это может быть единственный способ получить верхнюю активность в стеке без добавления ссылок на действия.