Kotlin-从对象调用类方法

时间:2018-07-25 11:47:14

标签: android kotlin kotlin-reflect

将尽量保持简洁...

我想在MainActivty类中有一个方法,例如updateUI()。

我还有另一个文件,它是一个称为FBManager的对象。该对象本质上拥有“静态” firebase访问方法。例如,signInUser()

在活动中,我调用FBManager.signInUser()...它执行一些逻辑并遍历2个私有方法,而在最后一个私有方法中,我想本质上调用MainActivity.updateUI()…

这无法完成,因为kotlin没有静态方法,也无法将updateUI()设为静态。 MainActivity()。updateUI()编译但不正确,并且不想实例化新的MainActivity。 最后,我想到了将活动传递给第一个构造函数,如FBManager.signInUser(this)...但是在signInUser()之后,它转到了一个重写方法,该方法只能将bundle作为可选输入(但我没有相信您可以将活动捆绑在一起),因此我无法将活动引用传递给最终的私有方法.....

编辑:进一步阐述

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()
}
}

道歉...在手机上打字...

-结束编辑-

我希望这一切对我来说都是新手,并且很难解释我的问题(因为如果我真正地理解了这些问题,那么我可以提出一个解决方案。)

因此,按照标题,还有其他方法可以...从对象FBManager调用MainActivity中的方法吗?

3 个答案:

答案 0 :(得分:6)

这个例子怎么样? 活动

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()
    }
}

答案 1 :(得分:0)

  

,并且不能将updateUI()设为静态。

是的!您希望在任何活动中尽量减少使用static东西。

我不知道您在Java方面有多强,但是对于这类问题,我经常使用所谓的观察者模式。您可能需要将其转换为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

答案 2 :(得分:0)

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

<?

MainActivity:

.html

FBManager:

interface Updatable {
    void updateUi();
}