我有一个实现监听器的Activity。我担心的是 活动可以重新创建,然后回调将有一个参考 到一个空的对象。
这意味着我们必须使用引用的新引用更新控制器 新创建的活动。
即使回调是异步的,最好使用哪种模式? 是否有一种安全的方法来更新线程中的控制器引用>安全的方式。
或
如果有人使用Headless片段并使用onAttach方法获取 更新参考。
或
是否应该不使用这些模式并使用Handler for 你所有的回调?
我怀疑我的updateListener方法在所有情况下都不起作用,例如。
1)init正忙,即将调用回调,标有行 * 10 *
2)重新创建活动并使用更新控制器 一个新的引用,但updateListener方法被阻止,因为即将发生回调。
3)回调执行并失败,因为侦听器引用变量是陈旧的。
public class Controller {
UserActionListener listener
static Controller instance;
public static synchronized Controller getInstance(UserActionListener listener) {
if (instance == null) {
instance = new Controller();
}
this.listener = listener;
return instance;
}
private Controller() {
//empty, enforce getInstance
}
private init() {
// do some very long running operation in a separate thread.
//.... on completion we update the UI
synchronized(Controller.class) {
/*10*/ listener.handle("SHOW DIALOG");
}
}
public void updateListener(UserActionListener listener) {
synchronized(Controller.class) {
this.listener = listener;
}
}
public class MainActivity extends AppCompatActivity implements UserActionListener {
static Controller controller;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
controller = Controller.getInstance(this);
if (savedInstanceState == null) {
//do not run on re-create
controller.init();
}
}
@Override
protected void onPostResume() {
super.onPostResume();
controller.updateListener(this);
}
@Override
public void handleAction(String userAction) {
switch (userAction) {
case "SHOW DIALOG" :
Toast.makeText(getActivity(),"Hello",Toast.LENGTH_LONG).show();
}
答案 0 :(得分:1)
您问题的直接答案是简单的订阅模式。 你打电话的活动:
@Override
public void onStart(){
controller.updateListener(this);
}
@Override
public void onStop(){
controller.updateListener(null);
}
并在控制器内部在侦听器上调用任何内容之前检查null。 但是逻辑上有一个根本性的缺陷。
使用以下代码:
static Controller controller;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
controller = new Controller(this);
}
具有对活动的引用的静态控制器正在泄漏活动,从而避免它被垃圾收集。
另外,即使你是控制器是静态的,你每次创建活动时都会创建一个新的控制器,同样在控制器init()
内你有以下内容:
// do some very long running operation
//....
这意味着这个长时间运行的操作是:
Service
。 答案 1 :(得分:0)
非常示例,使用WeakReference
进行活动