Kotlin - 从 object 调用 class 方法

Kotlin - Call class method from object

将尽量保持简洁...

我想在我的 MainActivty class 中有一个方法,比如 updateUI()。

我有另一个名为 FBManager 的 object 文件。 object 本质上拥有 "static" firebase 访问方法..比方说 signInUser()

从 Activity 我调用 FBManager.signInUser()... 它执行一些逻辑并通过 2 个私有方法移动,在最后一个私有方法中,我想基本上调用 MainActivity.updateUI()…

这无法完成,因为 kotlin 没有静态方法并且无法使 updateUI() 成为静态的。 MainActivity().updateUI() 编译但不正确并且不想实例化新的 MainActivity。 最后,我想将 activity 传递给第一个构造函数,如 FBManager.signInUser(this)... (而且我不相信你可以将活动放入一个包中),因此我无法将 activity 引用传递给最终的私有方法.....

编辑:进一步阐述

object FBManager {

fun signInUser() {
// Create intent
startActivityForResult(intent)
}

override fun onActivityResult(some intent stuff) {
//Try catch block. In try block call
firebaseAuth(Google account)
}

fun firebaseAuth(acct: GoogleSignInAccount) {
//More logic and an .onCompleteListener

// Inside .onCompeteListener, which is the problem....
MainActivity.updateUI()
}
}

抱歉布局...在我的 phone 上打字...

-结束编辑-

我希望所有这些都是有意义的,因为我是编程新手并且发现很难解释我的问题(因为如果我真正理解它们我可以想出一个解决方案..)

所以根据标题,有没有其他方法可以做到这一点...从 object FBManager 调用 MainActivity 中的方法?

and can't make updateUI() static.

没错!您想在任何活动中尽量减少 static 东西的使用。

我不知道你在 Java 上有多好,但我经常使用所谓的 observer-pattern 来解决这类问题。您可能需要将其转换为 Kotlin.

如果 MainActivity 是 运行,它注册接收来自 FBManager 的事件。

我经常使用 Telegram 中的以下代码:

public class NotificationCenter {

    private static int totalEvents = 1;

    public static final int updateActivity = totalEvents++;

    private final SparseArray<ArrayList<Object>> observers = new SparseArray<>();
    private final SparseArray<ArrayList<Object>> removeAfterBroadcast = new SparseArray<>();
    private final SparseArray<ArrayList<Object>> addAfterBroadcast = new SparseArray<>();

    private int broadcasting = 0;

    public interface NotificationCenterDelegate {
        void didReceivedNotification(int id, Object... args);
    }

    private static volatile NotificationCenter Instance = null;

    public static NotificationCenter getInstance() {
        NotificationCenter localInstance = Instance;
        if (localInstance == null) {
            synchronized (NotificationCenter.class) {
                localInstance = Instance;
                if (localInstance == null) {
                    Instance = localInstance = new NotificationCenter();
                }
            }
        }
        return localInstance;
    }

    public void postNotificationName(final int id, final Object... args) {
        if (Thread.currentThread() == ApplicationLoader.applicationHandler.getLooper().getThread()) {
            postNotificationNameInternal(id, args);
        } else {
            ApplicationLoader.runOnUIThread(new Runnable() {
                @Override
                public void run() {
                    postNotificationNameInternal(id, args);
                }
            });
        }
    }

    private void postNotificationNameInternal(int id, Object... args) {
        broadcasting++;
        ArrayList<Object> objects = observers.get(id);
        if (objects != null && !objects.isEmpty()) {
            for (int a = 0; a < objects.size(); a++) {
                Object obj = objects.get(a);
                ((NotificationCenterDelegate) obj).didReceivedNotification(id, args);
            }
        }
        broadcasting--;
        if (broadcasting == 0) {
            if (removeAfterBroadcast.size() != 0) {
                for (int a = 0; a < removeAfterBroadcast.size(); a++) {
                    int key = removeAfterBroadcast.keyAt(a);
                    ArrayList<Object> arrayList = removeAfterBroadcast.get(key);
                    for (int b = 0; b < arrayList.size(); b++) {
                        removeObserver(arrayList.get(b), key);
                    }
                }
                removeAfterBroadcast.clear();
            }
            if (addAfterBroadcast.size() != 0) {
                for (int a = 0; a < addAfterBroadcast.size(); a++) {
                    int key = addAfterBroadcast.keyAt(a);
                    ArrayList<Object> arrayList = addAfterBroadcast.get(key);
                    for (int b = 0; b < arrayList.size(); b++) {
                        addObserver(arrayList.get(b), key);
                    }
                }
                addAfterBroadcast.clear();
            }
        }
    }

    public void addObserver(Object observer, int id) {
        if (broadcasting != 0) {
            ArrayList<Object> arrayList = addAfterBroadcast.get(id);
            if (arrayList == null) {
                arrayList = new ArrayList<>();
                addAfterBroadcast.put(id, arrayList);
            }
            arrayList.add(observer);
            return;
        }
        ArrayList<Object> objects = observers.get(id);
        if (objects == null) {
            observers.put(id, (objects = new ArrayList<>()));
        }
        if (objects.contains(observer)) {
            return;
        }
        objects.add(observer);
    }

    public void removeObserver(Object observer, int id) {
        if (broadcasting != 0) {
            ArrayList<Object> arrayList = removeAfterBroadcast.get(id);
            if (arrayList == null) {
                arrayList = new ArrayList<>();
                removeAfterBroadcast.put(id, arrayList);
            }
            arrayList.add(observer);
            return;
        }
        ArrayList<Object> objects = observers.get(id);
        if (objects != null) {
            objects.remove(observer);
        }
    }
}

然后让你的 MainActivity 看起来像这样:

public class MainActivity implements NotificationCenter.NotificationCenterDelegate {

    @Override
    public void onPause() {
        NotificationCenter.getInstance().removeObserver(this, NotificationCenter.updateActivity);
        super.onPause();
    }

    @Override
    public void onResume() {
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateActivity);
        super.onResume();
    }

    @Override
    public void didReceivedNotification(int id, Object... args) {
        if (id == NotificationCenter.updateActivity) {
            UpdateUI();
        }
    }
}

然后在你的 FBManager:

NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateActivity, optionalData);

在此处查看此实现的其他代码:https://github.com/gi097/MyWindesheim/tree/master/app/src/main/java/com/giovanniterlingen/windesheim

这个例子怎么样? activity

class ExampleActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)

        FBManager.signInUser {
            updateUI()
        }
    }

    private fun updateUI() {
        // update UI
    }
}

和 FBManager 对象

object FBManager {
    fun signInUser(callback: () -> Unit) {
        // do work and then
        callback()
    }
}

您可以创建接口以在 FBManager 和 MainActivity 之间进行交互。例如:

interface Updatable {
    void updateUi();
}

主要活动:

class MainActivity implements Updatable {
    ...
    @Override
    void updateUi()
    ...
    FBManager.signInUser(this)
    ...
}

FBManager:

object FBManager {
    ...
    void signInUser(Updatable callback) {
        ...
        callback.updateUi()
        ...
    }
}