Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing View.setOnClickListener() defined through XML

I'm using AspectJ with Android and I'm successfully capturing calls to View.setOnClickListener() with this aspect:

public aspect Test {

    pointcut callPointcut(View view, OnClickListener listener) : call(void View.setOnClickListener(OnClickListener)) && target(view) && args(listener);

    @SuppressAjWarnings // Exported advice
    before(View view, OnClickListener listener) : callPointcut(view, listener)
    {
        Log.d("AspectJ", "Attempt to set onClick listener on view " + Integer.toHexString(view.getId()));
        Log.d("AspectJ", "Aspect has executed.");
        Log.d("AspectJ", listener.toString());
    }
}

Unfortunately, this does not capture listeners set up with android:onClick in the layout XML. Is there any way to capture this?

like image 980
m0skit0 Avatar asked Nov 27 '22 18:11

m0skit0


2 Answers

You wont be able to do that that way.

If I'm understanding it correctly your listening to calls of setOnClickListener() on Views.

When you set the onclick attribute in xml, its never called. The Listener is set when the View is created - directly. setOnClickListener() is never called.

The only solution would be to check all your views by hand - which is not recommend and probably not what youre looking for.

like image 55
Yalla T. Avatar answered Dec 04 '22 13:12

Yalla T.


I'm not 100% sure if this will work, but why not modify the View class to have an mOnClickListener attribute. Then when the OnClickListener is about to be set in the custom View class, set the attribute to "new OnClickListener(){ ... }" then call setOnClickListener with the attribute. You would then add a public method called getOnClickListener(), which you could call on your custom View object to return said listener.

This may be a roundabout / tedious way, because you would also need to include not only your custom View class, but every subclass of View that you plan on using in your XML and change their superclasses to use your custom View, not Android's. Then, you would need to change your XML elements to reflect that, i.e. com.yourpackage.Button, etc.

like image 21
dennisdrew Avatar answered Dec 04 '22 13:12

dennisdrew