0

I was wondering if I could change the way my method function, similar to Blocks iOS.

So I have this interface create in class API.java

 public interface APIListener {
        void apiResponseSuccess(String output);

        void apiResponseFailed(String output);
    }
public APIListener listener = null;
public void myMethod{
listener.apiResponseSuccess("output");
}

In order to call my interface created, i have to implements API.APIListener. and override the functions

@Override
    public void apiResponseSuccess(Object output) {
        Log.i("output from api",(String) output);
    }

    @Override
    public void apiResponseFailed(String output) {

    }

And to call it, I have to use :

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        API api = new API();
        api.listener = this;
        api.myMethod();    

    }

But drawbacks using this, It's hard to maintain if I call many methods inside the API, because all the results will go to apiResponseSuccess in my class, and have to tag which one coming from. Where the iOS comes with Blocks, it becomes easier. so basically, Is there a way to return the interface methods direct when we call it. similar to this

   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        API api = new API();
        api.listener = this;
        api.myMethod(
             public void apiResponseSuccess(Object output) {
             Log.i("output from api",(String) output);
            }
             public void apiResponseFailed(String output) {

            }); //so the result will go in separately inside the where the function is called.
    }
HelmiB
  • 12,303
  • 5
  • 41
  • 68

1 Answers1

2

You can achieve it easily.

Your api method should get APIListener as a parameter - so when you'll call it you'll have something like this:

api.myMethod(new APIListener() {
  @Override
  public void apiResponseSuccess(Object output) {
    Log.i("output from api",(String) output);
  }

  @Override
  public void apiResponseFailed(String output) {

  }
});

You can also pass more params of course:

api.myMethod(new APIListener() {
  @Override
  public void apiResponseSuccess(Object output) {
    Log.i("output from api",(String) output);
  }

  @Override
  public void apiResponseFailed(String output) {

  }
}, "my String", true);

BUT... notice that with your current implementation that the activity is the listener of your API call you'll have a memory leak!

You can solve it in several ways:

  1. Don't make the listener anonymous ("ios block") but an inner static class that takes the activity as a WeakReference
  2. Encapsulate the WeakReference inside your API and manage your listeners there.
MarkySmarky
  • 1,609
  • 14
  • 17
  • So I modify `myMethod` to `public void myMethod(APIListener apiListener)`. and how to add more parameters, for example : `public void myMethod(APIListener apiListener, String param1, String param2)`. how to call it ? – HelmiB Sep 17 '15 at 02:28
  • 1
    Exactly like you wrote - straight forward. see my updated answer. – MarkySmarky Sep 17 '15 at 10:06