我正在创建一个库。它会创建一个活动,启动它,并在按下按钮后完成它。
按下按钮后,我想通过界面执行一些客户端代码。
也就是说,这个库的用户传入一个实现,我只是执行它。
类似的iOS代码将是:
MyViewController *vc = [[MyViewController alloc] init];
vc.callOnComplete = ...
[self presentViewController:vc animated:YES completion:nil];
所需的代码是:
public interface SaveStuff {
void save();
}
在我的图书馆活动中:
private SaveStuff saveStuff;
public void onButtonClicked(View v) {
saveStuff.save() // client passes in saveStuff obj
finish();
}
我尝试过序列化。我创建了一个实现该接口的类,并实现了Serializable
,并尝试将其传递并使用getSerializableExtra
将其解压缩。我最终获得了一个非序列化的异常。据我所知,这可能不是一个可行的解决方案,因为它意味着客户端必须在其实现中仅使用可序列化的类。如果我错了,请纠正我。在我的试验中,客户活动显示在非序列化的例外中。
我尝试过使用静态参考。基本上是全球州/单身人士。事实证明,根据各种答案,例如:Java Static Variable becomes null,我不能依赖任何静态状态,任何与静态有效的解决方案都只是巧合。
我还没有尝试使用startActivityForResult
简单地启动活动,因为这需要我将我们接受的上下文作为参数投射到Activity。
该活动在内部库中启动:
private void startNewActivity(int newVersion) {
Intent i = new Intent(context, MyActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i); // context variable is passed in by the client
}
如您所见,客户端传递了上下文。我可以将上下文强制转换为活动以致电startActivityForResult
,但我不想这样做,因为我读过这并不总是安全的。我可以要求传递Activity
。这可能是一个合理的要求,但我还不想去那里。
我已经查看了现有的问题,我还没有尝试使用广播。如果我错误地想到这一点,请纠正我,但我能做的最好的事情是将对客户端接口实现的引用保持为广播接收器,然后在我创建的活动中发送广播。但是我担心接收器不会持续存在。如果我的库向用户显示活动,但用户在按下按钮之前杀死了应用程序,会发生什么?客户端代码的引用由上一个活动保存。按下按钮什么都不会发生?
我应该只是广播一条消息,并将其留给客户处理这些案件吗?客户如何处理这个?在app启动/关闭时注册一些东西?我是否必须强制用户执行此操作才能使用我的库?这是合理的吗?
更新
事实证明,我们只是让图书馆中的活动访问单身人士。 为了避免基于被杀死的活动等而擦除状态的所有问题,该库的用户将被要求运行“设置”。单例上的方法,并在那里传递回调obj。他们将在某种基础Activity onResume上运行它。 在回答这个问题的自我回答之前,我会稍等一下,看看是否还有其他选择。
答案 0 :(得分:0)
为什么不为Android使用相同的过程,即 1)建立一个界面 2)在您的活动中声明接口的公共变量。 3)用户将在开始启动您的活动时初始化该界面。 4)使用接口变量来调用方法。