Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct context to use within callbacks

The title pretty much says it all. If you have a callback from one class to another and need to call some method from within the callback that requires a context what is the correct context to use? A common example would be an AsyncTask with a callback to the Activity or Fragment that used it.

I generally try to avoid using getApplicationContext() but I cannot use this as the context from within a callback. Is this a case where using a broader context is appropriate?

To clarify further I'm thinking of a callback with an interface between an AsyncTask and an activity. Once I'm inside the overridden interface method I can't get the activities context from within there.

like image 337
Rarw Avatar asked Aug 14 '13 19:08

Rarw


People also ask

How do you call a function from a callback?

A callback is a function passed as an argument to another function. Using a callback, you could call the calculator function ( myCalculator ) with a callback, and let the calculator function run the callback after the calculation is finished: Example. function myDisplayer (some) {.

Why are the callbacks simplified?

They are simplified to teach you the callback syntax. Where callbacks really shine are in asynchronous functions, where one function has to wait for another function (like waiting for a file to load). Asynchronous functions are covered in the next chapter.

How to bind a callback to a value?

The functions/methods accepting callbacks may also accept a value to which this of the callback should refer. It is the same as binding yourself, but the method/function is doing it instead of you: So, the first argument is the callback, and the value this should refer to the second one.

What is the first argument of a callback in JavaScript?

So, the first argument is the callback, and the value this should refer to the second one. Another common expression of this problem is when an object method is used as a callback handler. Functions are prior in JavaScript, and the term “method” is considered a colloquial naming for a function, which is a value of an object property.


1 Answers

Use the Activity's context. Example:

MyAsyncTask mat = new MyAsyncTask(this);

MyAsyncTask contructor:

public MyAsyncTask(MyActivity context) {
    mContext = context;
}

To call MyActivity's method methodToCall() from within MyAsyncTask:

((MyActivity)mContext).methodToCall();

Edit 1:

I am guessing your problem is this:

public class MyActivity extends Activity {

    Button b;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.some_layout);

        b = (Button) findViewById(...);

        b.setOnClickListener(new OnClickListener() {    
            @Override
            public void onClick(View v) {
                Button newButton = new Button(this);        // Won't work!!
            }
        });
    }
}

Workaround:

  • Declare a method in MyActivity: getContext()

    public Context getContext() {
        return (Context)this;
    }
    
    b.setOnClickListener(new OnClickListener() {    
        @Override
        public void onClick(View v) {
            Button newButton = new Button(getContext());    // Will work
        }
    });
    
  • Use MyActivity.this in place of this.

  • Another way is to state that MyActivity implements the interface:

    public class MyActivity extends Activity implements View.OnClickListener {
    
        ....
        ....
    
        @Override
        public void onClick(View v) {
            Button newButton = Button (this)                // Will Work
        }
    }
    
like image 101
Vikram Avatar answered Sep 22 '22 03:09

Vikram