Bug 30758 - problem with Android.OS.Handler in C#
Summary: problem with Android.OS.Handler in C#
Status: RESOLVED ANSWERED
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 5.2
Hardware: PC Windows
: Normal normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2015-06-03 18:01 UTC by deceschevalier
Modified: 2015-06-15 10:53 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description deceschevalier 2015-06-03 18:01:10 UTC
When I want to create a custom widget based on ImageView.

The code in java is like:

public class MyImageView extends ImageView {
	
	public MyImageView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		camera = new Camera();
	}

	public MyImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		camera = new Camera();
	}
        Handler test  = new Handler(){
            Matrix matrix = new Matrix();
            setImageMatrix(matrix);
        };
}

But in C# I can not code like this. Even I tried use Handler(Action<Message>), I still can't handle the ImageMatrix.
Comment 1 Jonathan Pryor 2015-06-04 06:38:59 UTC
> The code in java is like:

Your code doesn't make sense to me. Specifically, I don't see how this compiles:

        Handler test  = new Handler(){
            Matrix matrix = new Matrix();
            setImageMatrix(matrix);
        };

Attempting to create a minimal repro suggests that javac doesn't like it either:

error: invalid method declaration; return type required
		setImageMatrix(matrix);
		^

See also:

https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html#syntax-of-anonymous-classes

> The anonymous class expression consists of the following:
> ...
> * A body, which is a class declaration body. More specifically, in the body,
>   method declarations are allowed but statements are not.

setImageMatrix(matrix) is a statement, not a field declaration (like matrix), nor a method declaration.

It could work if you had:

        Handler test  = new Handler(){{
            Matrix matrix = new Matrix();
            setImageMatrix(matrix);
        }};

Note the extra set of curly braces; the above provides a default constructor for the anonymous inner class, and the default constructor invokes creates the Matrix instance and calls setImageMatrix().

However, while that compiles, that's not what you wrote, and I don't understand what you wrote, or the intent of what you wrote.
Comment 2 deceschevalier 2015-06-12 14:34:30 UTC
i'm sorry i didn't make myself clear. 

the java code is like this

private Handler testHandler = new Handler() {
	private Matrix matrix = new Matrix();
	private float count = 0;

	@Override
	public void handleMessage(Message msg) {
        

        }
};

my problem is it seems there is no way to override the handleMessage in a Handler when i use c#.

and im sure the code above this time could work
Comment 3 Jonathan Pryor 2015-06-12 15:32:02 UTC
> private Handler testHandler = new Handler() {...};

This is an anonymous inner class. C# doesn't support anonymous inner classes, so make it an explicit class:

    // C#
    class MyTestHandler : Handler {
        Matrix matrix = new Matrix ();
        float count = 0;

        public override void HandleMessage (Message msg)
        {
            // ...
        }
    }

    // ...
    Handler testHandler = new MyTestHandler();
Comment 4 deceschevalier 2015-06-13 03:37:32 UTC
But if I make a explicit class, it can not use the variable in main class
Comment 5 Jonathan Pryor 2015-06-15 10:53:09 UTC
> But if I make a explicit class, it can not use the variable in main class

You can, it's just more complicated:

    class Outer {
        int value;

        class Inner {
            Outer self;
            public Inner(Outer self)
            {
                this.self = self;
                self.value++;
            }
        }
    }

You just need to change MyTestHandler to take a reference to the class to modify, and then it can access the fields within that class. (Nested classes can access all members of their enclosing scope.)