meraki-analytics / orianna

A Java framework for the Riot Games League of Legends API (http://developer.riotgames.com/).
MIT License
182 stars 56 forks source link

Question about ASyncRiotAPI #20

Closed JeffreyCA closed 9 years ago

JeffreyCA commented 9 years ago

I'm new to Android Programming, and I was wondering, why is using AsyncRiotAPI a lot different than using RiotAPI?

For example, to do the same thing as this:

Summoner summoner = RiotAPI.getSummonerByName("FatalElement");
System.out.println(summoner.getName() + " is a level " + summoner.getLevel() + " summoner on the NA server.");

How come for Android programming (by using Async) it has to be like this:

AsyncRiotAPI.getSummonerByName(new Action<Summoner>() {
   @Override
   public void perform(Summoner summoner) {
      System.out.println(summoner.getName() + " is a level " + summoner.getLevel() + " summoner on the NA server.");
   }

   public void handle(APIException e) {
      System.out.println("Couldn't get summoner FatalElement");
   }
}, "FatalElement");

and not just: Summoner summoner = AsyncRiotAPI.getSummonerByName("FatalElement"); System.out.println(summoner.getName() + " is a level " + summoner.getLevel() + " summoner on the NA server."); ?

robrua commented 9 years ago

Android doesn't allow you to do network operations on the main thread, since that thread is tasked with maintaining the GUI and it would freeze up while you wait for the network operation.

The AsyncRiotAPI makes you include an Action because it's going to go off and get the data from Riot, but you don't know when it's going to finish. Since your main thread isn't waiting around to get that data, you need to specify otherwise what you want to do with that data when it DOES come back from Riot.

Perform specifies what should be done with the data if it comes back properly, and Handle specifies what to do if an exception occurs while trying to get the data. These will be executed sometime in the future once the call to Riot's servers has been made.

This pattern is called a "Callback" and you can get more info here.

Unfortunately, since I don't want to maintain a separate codebase for both desktop Java and Android, the AsyncRiotAPI doesn't handle Android programming seamlessly. Much like you can't do networking on the main thread, you can't manage the GUI from any other thread, so you'll have to use tricks like this method to edit the GUI from within an Action.

Alternatively, you can use Android's more standard AsyncTask to do your networking on a separate thread, and just use the normal RiotAPI from Orianna.

JeffreyCA commented 9 years ago

Thanks for the reply.

I have a question, if I want to set a TextView (tview.setText()) to have the summoner level (summoner.getLevel()), as well as other League data, how would I do that using your AsyncRiotAPI? I can't update UI contents directly in your Perform section. Is there a way to implement an onPostExecute method?

JeffreyCA commented 9 years ago

Or how do you pass data from AsyncRiotAPI to other activities, etc.?

robrua commented 9 years ago

Hey - I've never done any significant work in Android, so I'm definitely not the authority on the subject. It seems to me based on reading some documentation that you can use runOnUiThread if you're just trying to set a GUI element based on data from the API. If you need to pass it between activities you'll probably just want to use the normal RiotAPI and use AsyncTasks as normal.

JeffreyCA commented 9 years ago

Alright, thanks. I'll try that!