Bug 22943 - Binding library does not register Activities
Summary: Binding library does not register Activities
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: Bindings ()
Version: 4.16.0
Hardware: PC Windows
: Normal normal
Target Milestone: ---
Assignee: Atsushi Eno
URL:
Depends on:
Blocks:
 
Reported: 2014-09-12 13:05 UTC by Tomasz Cielecki
Modified: 2014-09-22 04:36 UTC (History)
3 users (show)

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


Attachments
Sample project (181.26 KB, application/x-zip-compressed)
2014-09-12 13:05 UTC, Tomasz Cielecki
Details


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 FIXED

Description Tomasz Cielecki 2014-09-12 13:05:58 UTC
Created attachment 8039 [details]
Sample project

When attempting to bind an AAR with Activities inside, they do not get registered in the AndroidManifest, which means, when attempting to launch any of them, they will crash the app telling that Android cannot find them.

I've attached a sample project binding the CropImage library from: https://github.com/lvillani/android-cropimage

The AAR is generated with Android Studio using gradle build, everything in the AAR seems to be OK, and the binding project generates classes etc. The Activities are just not registered.

Do we really have to manually register these?
Comment 1 Ram Chandra 2014-09-15 12:10:34 UTC
I can't reproduce this, we may have to see if a developer can figure out what's going on. If you have a chance, it might also be helpful to include build information:

You can get build information form here:

Xamarin Studio=> Help => About=> Show details => Copy Information.

I tried attached sample on Mac machine and I am able to build and deploy the attached sample successfully, I am not getting any error or exception. However, when I try the same on windows machine I am getting build error i.e "The type or namespace name 'Com' could not be found (are you missing a using directive or an assembly reference?)"

Environment Info:

=== Xamarin Studio ===

Version 5.5 (build 185)
Installation UUID: 851620d2-e950-4682-b459-991ccec9d895
Runtime:
	Microsoft .NET 4.0.30319.18408
	GTK+ 2.24.22 (MS-Windows theme)
	GTK# 2.12.25

=== Xamarin.Android ===

Version: 4.16.0 (Enterprise Edition)
Android SDK: D:\SDK\AndroidSDK
	Supported Android versions:
		1.6    (API level 4)
		2.1    (API level 7)
		2.2    (API level 8)
		2.3    (API level 10)
		3.0    (API level 11)
		3.1    (API level 12)
		3.2    (API level 13)
		4.0    (API level 14)
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		4.5    (API level 21)
Java SDK: C:\Program Files (x86)\Java\jdk1.6.0_31
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b05)
Java HotSpot(TM) Client VM (build 20.6-b01, mixed mode, sharing)

=== Build Information ===

Release ID: 505000185
Git revision: 31ed07d70102b543b3658da1bdfc1936798e8a89
Build date: 2014-09-12 20:03:05-04
Xamarin addins: 219ade5bee1af21074662c240e94c52dec972619

=== Operating System ===

Windows 6.1.7601.65536 (64-bit)
Comment 2 Tomasz Cielecki 2014-09-16 09:06:42 UTC
It is not that it does not build. However, the CropImage.aar has two Activities, namely MonitoredActivity and NoSearchActivity, these are not added to the resulting AndroidManifest when building. So at runtime when calling:

    var cropImage = new CropImageIntentBuilder(200, 200, croppedImage);
    
    cropImage.SetSourceImage(data.Data);
    var intent = cropImage.GetIntent(this);
    StartActivityForResult(intent, RequestCropPicture);

Which can be seen on line 59 in MainActivity in the Application project (CropImageExample) it will crash, saying that it cannot find the Activity, since it hasn't been registered in the AndroidManifest.
Comment 3 Tomasz Cielecki 2014-09-16 09:09:20 UTC
Xamarin   3.6.223.0 (2a296d4cb2e4c8c0b356044ed533966d042d2a0f)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android   4.16.0.14 (62e09eb09d3a9056653f1ef497de30b53bf04f47)
Visual Studio plugin to enable development for Xamarin.Android.

Xamarin.iOS   8.0.25.0 (f214120dfd56535e76462749eee1cf1abb6687c5)
Visual Studio extension to enable development for Xamarin.iOS.

Even building it in Xamarin.Studio it does not add the Activities in the AndroidManifest. Here is the resulting one:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="CropImageExample.CropImageExample" android:versionCode="1" android:versionName="1.0">
  <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="19" />
  <application android:label="CropImageExample" android:icon="@drawable/icon" android:name="mono.android.app.Application" android:debuggable="true">
    <activity android:icon="@drawable/icon" android:label="CropImageExample" android:name="cropimageexample.MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="CropImageExample.CropImageExample.mono.MonoRuntimeProvider.__mono_init__" />
    <receiver android:name="mono.android.Seppuku">
      <intent-filter>
        <action android:name="mono.android.intent.action.SEPPUKU" />
        <category android:name="mono.android.intent.category.SEPPUKU.CropImageExample.CropImageExample" />
      </intent-filter>
    </receiver>
  </application>
  <uses-permission android:name="android.permission.INTERNET" />
</manifest>
Comment 4 Atsushi Eno 2014-09-17 03:48:04 UTC
(quick Q @jonp: is there any reason we should NOT generate <activity> element where [RegisterAttribute (DoNotGenerateAcw = true)] ? We totally disable <activity> element generation for any Activity (or any JLO) that has DoNotGenerateAcw as true. My wild guess is it is only for optimization and actually wouldn't harm performance a lot if we don't skil it.)

Basically, anyone with custom Activity classes should register those activities manually, not automatically. It is because there is no way to automatically judge which should generate <activity>. Think about this example:

public class SomeBaseActivity extends Activity { ... } // I do NOT want to be exposed
public class ExposedActivity extends SomeBaseActivity { ... } // I DO want to be exposed
public class FurtherSpecialActivity extends ExposedActivity { ... } // I DO want to be exposed

Any activities that need to be exposed should have corresponding *additional* attribute declaration like this:

----
using System;
using Android.App;

namespace Xamarin.Droid.Camera
{
	[Activity (Name="com.android.camera.MonitoredActivity")]
	public partial class MonitoredActivity
	{
	}
	[Activity (Name="com.android.camera.NoSearchActivity")]
	public partial class NoSearchActivity
	{
	}
}
----

However, while it SHOULD work, it doesn't. It is because we somehow prevent <activity> element generation if the target Activity class is in a binding dll (precisely to say, those Activity classes that have [Register] attribute and its has DoNotGenerateAcw property as true). Unless there is particular reason we do so, we should fix it.
Comment 5 Jonathan Pryor 2014-09-17 12:07:34 UTC
> is there any reason we should NOT generate <activity> element
> where [RegisterAttribute (DoNotGenerateAcw = true)]

No. I agree with your proposal: if a type with [Register(DoNotGenerateAcw =true)] is present AND it has an [Activity] attribute, then we should generate an entry for it within AndroidManifest.xml.

> It is because we somehow prevent <activity> element generation 
> if the target Activity class is in a binding dll

It's not that we actively "prevent" it; it's that we didn't consider this case.

What happens is that we compute the list of all types that we need to generate Java ACW's for, generate the ACWs, and then use this list to generate AndroidManifest.xml. Since [Register(DoNotGenerateAcw=true)] types by definition won't get ACWs, they are not present in the list used to generate AndroidManifest.xml.

See also the GenerateJavaStubs task and the java_types population.
Comment 6 Tomasz Cielecki 2014-09-18 05:07:00 UTC
I might be spoiled by the gradle build system used when developing Java Android apps, but I believe it is capable of merging AndroidManifest.xml files from library projects into the application project. Meaning all registered Activities in an AAR, will get merged in and accessible. However, this AAR in particular does not have anything exciting in the manifest.

You can read more about the gradle manifest merger here: http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger

However, registering Activities as proposed by Atsushi Eno in Comment 4, would be a good start.
Comment 7 Atsushi Eno 2014-09-19 08:08:32 UTC
AndroidManifest.xml in CropImage aar project does NOT declare CropImage <activity> element. It is declared in AndroidManifest.xml in CropImageExample project. I don't see any working example of auto merging AndroidManifest.xml there.
Comment 8 Tomasz Cielecki 2014-09-19 08:12:34 UTC
Indeed, which is what I meant with that the AAR in the binding project in the sample I provided, does not have anything exciting in the manifest. So you are absolutely right, in this case, even with gradle manifest merger, nothing would happen and they would not be registered.
Comment 9 Atsushi Eno 2014-09-19 08:24:49 UTC
The attrubute lookup is fixed in our sources, so the attributes in binding
types will be usable in the next branched release (which is likely 4.20 or any
newer).
Thanks for the report.

[master f07de18]
Comment 10 Atsushi Eno 2014-09-20 03:26:43 UTC
(The fix affects widely and causing some regression, reverted.)
Comment 11 Atsushi Eno 2014-09-22 04:36:21 UTC
(Fixed build. [master 8a692ea])

AndroidManifest.xml lookup for library project is logged as an internal wishlist task (trello).