1

Will try to keep this as concise as possible...

I would like to have a method in my MainActivty class, say updateUI().

I have another file that is an object called FBManager. That object essentially holds "static" firebase access methods.. let's say signInUser()

From the Activity I call FBManager.signInUser()... It does some logic and moves through 2 private methods and at the last private method, I would like to essentially call MainActivity.updateUI()…</p>

This can't be done as kotlin doesn't have static methods and can't make updateUI() static. MainActivity().updateUI() compiles but is incorrect and don't want to instantiate a new MainActivity. Lastly, I thought of passing the activity into the first constructor like FBManager.signInUser(this)... But after signInUser(), it goes to an override method that can only take a bundle as an optional input (and I don't believe you can put activities into a bundle), thus I can't pass the activity reference to the final private method.....

Edit: Further elaboration

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

Apologies for layout... Typing on my phone...

-end edit-

I hope all that makes sense as I'm new to programming and find it difficult to explain my problems (since if I truely understood them I could come up with a solution..)

So as per the title, is there any other way to do this... To call a method in MainActivity from an object FBManager?

4

3 回答 3

9

这个例子怎么样?活动

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()
    }
}
于 2018-07-25T11:58:23.350 回答
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

于 2018-07-25T11:52:42.237 回答
0

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

interface Updatable {
    void updateUi();
}

主要活动:

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

FB经理:

object FBManager {
    ...
    void signInUser(Updatable callback) {
        ...
        callback.updateUi()
        ...
    }
}
于 2018-07-25T11:58:53.850 回答