Oftentimes it can become necessary to access platform specific APIs, e.g., adding advertisement services or a leaderboard functionality. This can be achieved by allowing specific implementation to be defined through a common API interface.
Take the following example, which tries to use a very simple leaderboard API that is only available on Android. For other targets we simply want to log invocations or provide mock return values.
The Android API looks like this:
/** Let's assume this is the API provided by Swarm **/
public class LeaderboardServiceApi {
public void submitScore(String user, int score) { ... }
}
The first step is to create an abstraction of the API in form of an interface.
The interface is put into the core project:
public interface Leaderboard {
public void submitScore(String user, int score);
}
Next we create specific implementations for each platform and put these into their respective projects.
The following would go into the Android project:
/** Android implementation, can access LeaderboardServiceApi directly **/
public class AndroidLeaderboard implements Leaderboard {
private final LeaderboardServiceApi service;
public AndroidLeaderboard() {
// Assuming we can instantiate it like this
service = new LeaderboardServiceApi();
}
public void submitScore(String user, int score) {
service.submitScore(user, score);
}
}
The following would go into the desktop project:
/** Desktop implementation, we simply log invocations **/
public class DesktopLeaderboard implements Leaderboard {
public void submitScore(String user, int score) {
Gdx.app.log("DesktopLeaderboard", "would have submitted score for user " + user + ": " + score);
}
}
The following would go into the HTML5 project:
/** Html5 implementation, same as DesktopLeaderboard **/
public class Html5Leaderboard implements Leaderboard {
public void submitScore(String user, int score) {
Gdx.app.log("Html5Leaderboard", "would have submitted score for user " + user + ": " + score);
}
}
Next, the ApplicationListener
gets a constructor to which we can pass the concrete Leaderboard implementation:
public class MyGame implements ApplicationListener {
private final Leaderboard leaderboard;
public MyGame(Leaderboard leaderboard) {
this.leaderboard = leaderboard;
}
// rest omitted for clarity
}
In each starter class we then simply instantiate MyGame
, passing the corresponding Leaderboard implementation as an argument, e.g., on the desktop:
public static void main(String[] argv) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
new LwjglApplication(new MyGame(new DesktopLeaderboard()), config);
}
Further threading
A forum discussion on this matter, also mentioning iOS specific things.