我经常发现自己需要访问需要引用某些活动的方法。例如,要使用getWindowManager
,我需要访问一些 Activity。但通常我使用这些方法的代码位于其他没有引用活动的类中。到目前为止,我要么存储了对主要活动的引用,要么将某些活动的上下文传递给了类。有没有更好的方法来做到这一点?
12 回答
如果您已经有一个有效的上下文,只需使用这个:
Activity activity = (Activity) context;
传递上下文是参考活动的更好方法。
您可以将 Context 传递给另一个类。
活动中::
AnotherClass Obj = new AnotherClass(this);
在另一个班级
class AnotherClass{
public AnotherClass(Context Context){
}
}
您可以在活动中实现必要的方法并实现Handler。然后,只需将处理程序实例传递给您的类,您可以在其中获取处理程序的消息并将其发送到目标。
我找到了一种将 Activity 带到我没有在论坛中讨论过的非活动类的方法。这是在多次尝试使用 getApplicationContext() 并将上下文作为参数传递给构造函数的失败之后,这些尝试都没有提供 Activity。我看到我的适配器正在将传入的上下文转换为 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 之后,我可以在需要 Activity 上下文的任何地方使用 this.activity。
我是 android 新手,所以我的建议可能看起来很笨拙,但是如果您只是创建对您的活动的引用作为私有属性并在 OnCreate 方法中分配它呢?您甚至可以像这样使用 OnCreate 创建您的 CustomActivity,并从您的 CustomActivity 派生所有活动,而不是由 adnroid 提供的通用 Activity。
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
您可以使您的应用程序实例成为单例,并在需要 Context 时使用它
这个问题有一个例子:
Android Application as Singleton
这样,当您需要 Context 时,您可以使用
Context context = MyApplication.getInstance()
这可能不是最干净的解决方案,但到目前为止它对我来说效果很好
我们为此建立了一个框架。我们有一个BaseActivity
继承自的类,Activity
它覆盖了所有生命周期方法,并有一些静态(类)变量来跟踪活动堆栈。如果有任何东西想知道当前活动是什么,它只需调用一个静态方法,BaseActivity
该方法返回我们私有管理堆栈顶部的活动。
这有点hacky,但它有效。我不确定我会推荐它。
活动通信有多种方式。
您可以使用:
startActivityForResult 方法
广播消息和接收者的系统(你可以从实际活动中广播一个事件,并在目标活动中注册一个接收者。记住目标活动必须事先初始化且未完成)
- 正如您所说,在您需要的任何地方存储目标活动的引用。
处理您想要执行这些方法的类中的 Intent,并在 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 获取新数据。
我通过使单例类具有以下类的实例作为成员来解决此问题。
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() 分离时被释放。附加新对象时,将重用释放的整数。
从单例类:
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 可以用于任何其他类。
我希望这有帮助。
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;
}
只是一个猜测,因为我还没有这样做,但它可能会起作用。
1) 通过使您的 Android Application 类成为 Singleton 来获取您的 applicationContext。
2)从上下文中获取您的 ActivityManager 类。
3) 使用 ActivityManager 上的 getRunningTasks() 获取 RunningTaskInfos 列表。
4) 从列表中获取第一个 RunningTaskInfo 元素,该元素应该是最近启动的任务。
5) 在该 RunningTaskInfo 上调用 topActivity,它应该为您返回该任务的活动堆栈上的顶部活动。
现在,这似乎比这里提到的任何其他方法都要做更多的工作,但是您可能可以将其封装在一个静态类中并随时调用它。似乎它可能是在不添加对活动的引用的情况下获得堆栈顶部活动的唯一方法。