Skip to content

Commit f85a6ae

Browse files
committed
Merge branch 'main' into dev/grendel/xxhash3
* main: [templates] Remove redundant "template" from display name. (#8773) Bump to xamarin/Java.Interop/main@a7e09b7 (#8793) [build] Include MIT license in most NuGet packages (#8787) Bump to dotnet/installer@893b762b6e 9.0.100-preview.3.24153.2 (#8782) [docs] update notes about `dotnet-trace` and `dotnet-gcdump` (#8713)
2 parents 1a8e48c + 9d8ca60 commit f85a6ae

File tree

9 files changed

+142
-94
lines changed

9 files changed

+142
-94
lines changed

Documentation/guides/tracing.md

Lines changed: 119 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,138 @@
1-
# Using a device connected via USB
1+
# Tracing .NET Android Applications
22

3-
## Startup profiling
4-
### Set up reverse port forwarding:
3+
Attaching `dotnet-trace` to a .NET Android application, allows you to
4+
get profiling information in formats like `.nettrace` and
5+
`.speedscope`. These give you CPU sampling information about the time
6+
spent in each method in your application. This is quite useful for
7+
finding *where* time is spent in the startup or general performance of
8+
your .NET applications.
59

6-
Note that you can skip this step if the Android application is running on an
7-
Android emulator; it is only required for physical Android devices.
10+
To use `dotnet-trace` on Android, the following tools/components work
11+
together to make this happen:
812

9-
```sh
10-
$ adb reverse tcp:9000 tcp:9001
11-
```
12-
This will forward port 9000 on device to port 9001.
13+
* [`dotnet-trace`][dotnet-trace] itself is a .NET global tool.
1314

14-
_Alternatively:_
15-
```sh
16-
$ adb reverse tcp:0 tcp:9001
17-
43399
18-
```
19-
This will allocate a random port on remote and forward it to port 9001 on the host. The forwarded port is printed by adb
15+
* [`dotnet-dsrouter`][dotnet-dsrouter] is a .NET global tool that
16+
forwards a connection from a remote Android or iOS device or
17+
emulator to a local port on your development machine.
2018

21-
### Configure the device so that the profiled app suspends until tracing utility connects
19+
* [`dotnet-gcdump`][dotnet-gcdump] is a .NET global tool that can be
20+
used to collect memory dumps of .NET applications.
2221

23-
```sh
24-
$ adb shell setprop debug.mono.profile '127.0.0.1:9000,suspend'
25-
```
22+
* The Mono Diagnostic component, `libmono-component-diagnostics_tracing.so`,
23+
is included in the application and is used to collect the trace data.
24+
25+
See the [`dotnet-trace` documentation][dotnet-trace] for further details about its usage.
2626

27-
### Install `dotnet-dsrouter`
27+
[dotnet-trace]: https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace
28+
[dotnet-dsrouter]: https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-dsrouter
29+
[dotnet-gcdump]: https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-gcdump
2830

29-
Generally, you can use a stable `dotnet-dsrouter` from NuGet:
31+
## Install .NET Global Tools
32+
33+
Generally, you can install the required tooling such as:
3034

3135
```sh
36+
$ dotnet tool install -g dotnet-trace
37+
You can invoke the tool using the following command: dotnet-trace
38+
Tool 'dotnet-trace' was successfully installed.
3239
$ dotnet tool install -g dotnet-dsrouter
3340
You can invoke the tool using the following command: dotnet-dsrouter
3441
Tool 'dotnet-dsrouter' was successfully installed.
42+
$ dotnet tool install -g dotnet-gcdump
43+
You can invoke the tool using the following command: dotnet-gcdump
44+
Tool 'dotnet-gcdump' was successfully installed.
3545
```
3646

37-
Or use a build from the nightly feed `https://aka.ms/dotnet-tools/index.json`:
47+
You can also install prerelease builds from the nightly feed
48+
`https://aka.ms/dotnet-tools/index.json`:
3849

3950
```sh
4051
$ dotnet tool install -g dotnet-dsrouter --add-source=https://aka.ms/dotnet-tools/index.json --prerelease
52+
You can invoke the tool using the following command: dotnet-dsrouter
53+
Tool 'dotnet-dsrouter' was successfully installed.
4154
```
4255

43-
### Start the tracing router/proxy on host
56+
## Configuration & Setup
4457

45-
For profiling an Android application running on an Android emulator:
46-
```sh
47-
$ dotnet-dsrouter android-emu --verbose debug
48-
WARNING: dotnet-dsrouter is a development tool not intended for production environments.
58+
### Running `dotnet-dsrouter` on the Host
59+
60+
For profiling an Android application running on an Android *emulator*:
4961

50-
Start an application on android emulator with one of the following environment variables set:
62+
```sh
63+
$ dotnet-dsrouter android-emu
64+
How to connect current dotnet-dsrouter pid=1234 with android emulator and diagnostics tooling.
65+
Start an application on android emulator with ONE of the following environment variables set:
66+
[Default Tracing]
5167
DOTNET_DiagnosticPorts=10.0.2.2:9000,nosuspend,connect
68+
[Startup Tracing]
5269
DOTNET_DiagnosticPorts=10.0.2.2:9000,suspend,connect
70+
Run diagnotic tool connecting application on android emulator through dotnet-dsrouter pid=1234:
71+
dotnet-trace collect -p 1234
72+
See https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-dsrouter for additional details and examples.
73+
74+
info: dotnet-dsrouter-1234[0]
75+
Starting dotnet-dsrouter using pid=1234
76+
info: dotnet-dsrouter-1234[0]
77+
Starting IPC server (dotnet-diagnostic-dsrouter-1234) <--> TCP server (127.0.0.1:9000) router.
78+
```
5379

54-
info: dotnet-dsrouter[0]
55-
Starting dotnet-dsrouter using pid=21352
56-
dbug: dotnet-dsrouter[0]
57-
Using default IPC server path, dotnet-diagnostic-dsrouter-21352.
58-
dbug: dotnet-dsrouter[0]
59-
Attach to default dotnet-dsrouter IPC server using --process-id 21352 diagnostic tooling argument.
60-
info: dotnet-dsrouter[0]
61-
Starting IPC server (dotnet-diagnostic-dsrouter-21352) <--> TCP server (127.0.0.1:9000) router.
62-
dbug: dotnet-dsrouter[0]
63-
Trying to create new router instance.
64-
dbug: dotnet-dsrouter[0]
65-
Waiting for a new TCP connection at endpoint "127.0.0.1:9000".
66-
dbug: dotnet-dsrouter[0]
67-
Waiting for new ipc connection at endpoint "dotnet-diagnostic-dsrouter-21352".
80+
For profiling an Android application running on an Android *device*:
81+
82+
```sh
83+
# `adb reverse` is required when using hardware devices
84+
$ adb reverse tcp:9000 tcp:9001
85+
$ dotnet-dsrouter android
86+
How to connect current dotnet-dsrouter pid=1234 with android device and diagnostics tooling.
87+
Start an application on android device with ONE of the following environment variables set:
88+
[Default Tracing]
89+
DOTNET_DiagnosticPorts=127.0.0.1:9000,nosuspend,connect
90+
[Startup Tracing]
91+
DOTNET_DiagnosticPorts=127.0.0.1:9000,suspend,connect
92+
Run diagnotic tool connecting application on android device through dotnet-dsrouter pid=1234:
93+
dotnet-trace collect -p 1234
94+
...
6895
```
6996

70-
### For Android devices
97+
### Android System Properties
7198

72-
For profiling an Android application running on an Android device:
99+
Note the log message that `dotnet-dsrouter` prints that mentions
100+
`$DOTNET_DiagnosticPorts`. `$DOTNET_DiagnosticPorts` is an environment
101+
variable that could be defined in an `@(AndroidEnvironment)` file, but
102+
it is simpler to use the `debug.mono.profile` Android system property.
103+
Android system properties can be used without rebuilding the app.
73104

105+
For emulators, `$DOTNET_DiagnosticPorts` should specify an IP address
106+
of 10.0.2.2:
107+
108+
```sh
109+
$ adb shell setprop debug.mono.profile '10.0.2.2:9000,suspend,connect'
74110
```
75-
$ dotnet-dsrouter server-server -tcps 127.0.0.1:9001 --verbose debug
111+
112+
For devices, `$DOTNET_DiagnosticPorts` should specify an IP address of
113+
127.0.0.1, and the port number should be the [port used used with adb
114+
reverse](#start-the-tracing-routerproxy-on-host), e.g:
115+
116+
```sh
117+
# `adb reverse` is required when using hardware devices
118+
$ adb reverse tcp:9000 tcp:9001
119+
$ adb shell setprop debug.mono.profile '127.0.0.1:9000,suspend,connect'
76120
```
77121

78-
Eventually, we will be able to simply do `dotnet-dsrouter android` when
79-
[dotnet/diagnostics#4337][4337] is resolved. `adb reverse tcp:9000 tcp:9001` is
80-
also currently required as mentioned above.
122+
`suspend` is useful as it blocks application startup, so you can
123+
actually `dotnet-trace` startup times of the application.
124+
125+
If you are wanting to collect a `gcdump` or just get things working,
126+
try `nosuspend` instead. See the [`dotnet-dsrouter`
127+
documentation][nosuspend] for further information.
81128

82-
[4337]: https://github.com/dotnet/diagnostics/issues/4337
129+
[nosuspend]: https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-dsrouter#collect-a-trace-using-dotnet-trace-from-a-net-application-running-on-android
83130

84-
### Start the tracing client
131+
### Running `dotnet-trace` on the Host
85132

86133
First, run `dotnet-trace ps` to find a list of processes:
87134

88-
```
135+
```sh
89136
> dotnet-trace ps
90137
38604 dotnet-dsrouter C:\Users\myuser\.dotnet\tools\dotnet-dsrouter.exe "C:\Users\myuser\.dotnet\tools\dotnet-dsrouter.exe" android-emu --verbose debug
91138
```
@@ -95,7 +142,7 @@ connect *through it* appropriately.
95142

96143
Using the process ID from the previous step, run `dotnet-trace collect`:
97144

98-
```
145+
```sh
99146
$ dotnet-trace collect -p 38604 --format speedscope
100147
No profile or providers specified, defaulting to trace profile 'cpu-sampling'
101148

@@ -107,15 +154,23 @@ Waiting for connection on /tmp/maui-app
107154
Start an application with the following environment variable: DOTNET_DiagnosticPorts=/tmp/maui-app
108155
```
109156

110-
The `--format` argument is optional and it defaults to `nettrace`. However, `nettrace` files can be viewed only with
111-
Perfview on Windows, while the speedscope JSON files can be viewed "on" Unix by uploading them to https://speedscope.app
157+
The `--format` argument is optional and it defaults to `nettrace`.
158+
However, `nettrace` files can be viewed only with Perfview or Visual
159+
Studio on Windows, while the speedscope JSON files can be viewed "on"
160+
Unix by uploading them to [https://speedscope.app/][speedscope].
112161

113-
### Compile and run the application
162+
[speedscope]: https://speedscope.app/
114163

115-
```
164+
### Running the .NET Android Application
165+
166+
`$(AndroidEnableProfiler)` must be set to `true` as it includes the
167+
Mono diagnostic component in the application. This component is the
168+
`libmono-component-diagnostics_tracing.so` native library.
169+
170+
```sh
116171
$ dotnet build -f net8.0-android -t:Run -c Release -p:AndroidEnableProfiler=true
117172
```
118-
_NOTE: `-f net8.0-android` is only needed for projects with multiple `$(TargetFrameworks)`._
173+
*NOTE: `-f net8.0-android` is only needed for projects with multiple `$(TargetFrameworks)`.*
119174

120175
Once the application is installed and started, `dotnet-trace` should show something similar to:
121176

@@ -141,14 +196,8 @@ directory.
141196

142197
## How to get GC memory dumps?
143198

144-
If running on desktop, you can use the `dotnet-gcdump` global tool.
145-
This can be installed via:
146-
147-
```dotnetcli
148-
$ dotnet tool install --global dotnet-gcdump
149-
```
150-
151-
To use it, for example:
199+
If running on desktop, you can use the `dotnet-gcdump` global tool for
200+
local processes. For example:
152201

153202
```sh
154203
# `hw-readline` is a standard Hello World, with a `Console.ReadLine()` at the end
@@ -167,6 +216,7 @@ $ dotnet-gcdump collect -p 33972
167216
Writing gcdump to '.../hw-readline/20230314_113922_33972.gcdump'...
168217
Finished writing 5624131 bytes.
169218
```
219+
170220
See the [`dotnet-gcdump` documentation][dotnet-gcdump]
171221
for further details about its usage.
172222

@@ -188,6 +238,9 @@ $ dotnet-gcdump collect -p 38604
188238

189239
This will create a `*.gcdump` file in the current directory.
190240

241+
Note that using `nosuspend` in the `debug.mono.profile` property is
242+
useful, as it won't block application startup.
243+
191244
## Memory Dumps for Android in .NET 7
192245

193246
In .NET 7, we have to use th older, more complicated method for collecting
@@ -228,12 +281,11 @@ This saves a `foo.gcdump` that you can open in Visual Studio.
228281
See the [dotnet/runtime documentation][gc-dumps-on-mono] for
229282
additional details.
230283

231-
[dotnet-gcdump]: https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-gcdump
232284
[mono-events]: https://github.com/dotnet/runtime/blob/c887c92d8af4ce65b19962b777f96ae8eb997a42/src/coreclr/vm/ClrEtwAll.man#L7433-L7468
233285
[dotnet-trace-help]: https://github.com/dotnet/diagnostics/blob/6d755e8b5435b1380c118e9d81e075654b0330c9/documentation/dotnet-trace-instructions.md#dotnet-trace-help
234286
[gc-dumps-on-mono]: https://github.com/dotnet/runtime/blob/728fd85bc7ad04f5a0ea2ad0d4d8afe371ff9b64/docs/design/mono/diagnostics-tracing.md#collect-gc-dumps-on-monovm
235287

236-
## How to `dotnet trace` our build?
288+
## How to `dotnet trace` a Build?
237289

238290
Setting this up is easy, the main issue is there end up being
239291
potentially *a lot* of threads (30-40) depending on the build.

LICENSE renamed to LICENSE.TXT

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
Xamarin.Android SDK
2-
31
The MIT License (MIT)
42

5-
Copyright (c) .NET Foundation Contributors
3+
Copyright (c) .NET Foundation and Contributors
64

75
All rights reserved.
86

@@ -23,4 +21,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2321
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2422
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2523
SOFTWARE.
26-

build-tools/create-packs/Directory.Build.targets

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
<Target Name="_SetGlobalProperties">
4848
<ItemGroup>
4949
<_GlobalProperties Include="-p:Configuration=$(Configuration)" />
50-
<_GlobalProperties Include="-p:NuGetLicense=$(NuGetLicense)" />
5150
<_GlobalProperties Include="-p:IncludeSymbols=False" />
5251
</ItemGroup>
5352
</Target>
@@ -103,7 +102,7 @@
103102
/>
104103
<!-- The .nupkg contains the files under /data/, so we need to move them -->
105104
<ItemGroup>
106-
<_WLExtractedFiles Include="$(_SdkManifestsFolder)temp\LICENSE" />
105+
<_WLExtractedFiles Include="$(_SdkManifestsFolder)temp\LICENSE.TXT" />
107106
<_WLExtractedFiles Include="$(_SdkManifestsFolder)temp\data\*" />
108107
</ItemGroup>
109108
<Move SourceFiles="@(_WLExtractedFiles)" DestinationFolder="$(_SdkManifestsFolder)microsoft.net.sdk.android" />

build-tools/create-packs/License.targets

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
<!-- Ownership and LICENSE settings for .nupkg's -->
1+
<!-- Ownership and LICENSE.TXT settings for .nupkg's -->
22
<Project>
33
<PropertyGroup>
44
<Authors>Microsoft</Authors>
55
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
66
<PackageProjectUrl>https://github.com/xamarin/xamarin-android</PackageProjectUrl>
77
<NuGetLicense Condition="Exists('$(XamarinAndroidSourcePath)external\monodroid\tools\scripts\License.txt')">$(XamarinAndroidSourcePath)external\monodroid\tools\scripts\License.txt</NuGetLicense>
8-
<NuGetLicense Condition=" '$(NuGetLicense)' == '' ">$(XamarinAndroidSourcePath)LICENSE</NuGetLicense>
9-
<PackageLicenseFile>LICENSE</PackageLicenseFile>
8+
<NuGetLicense Condition=" '$(NuGetLicense)' == '' or '$(PackageId)' != 'Microsoft.Android.Sdk.$(HostOS)' ">$(XamarinAndroidSourcePath)LICENSE.TXT</NuGetLicense>
9+
<PackageLicenseFile>LICENSE.TXT</PackageLicenseFile>
1010
<BeforePack>_GetLicense;$(BeforePack)</BeforePack>
1111
</PropertyGroup>
1212
<Target Name="_GetLicense">

eng/Version.Details.xml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
<Dependencies>
22
<ProductDependencies>
3-
<Dependency Name="Microsoft.Dotnet.Sdk.Internal" Version="9.0.100-preview.3.24126.2">
3+
<Dependency Name="Microsoft.Dotnet.Sdk.Internal" Version="9.0.100-preview.3.24153.2">
44
<Uri>https://github.com/dotnet/installer</Uri>
5-
<Sha>d070660282eb5f78497310f77093638744112e03</Sha>
5+
<Sha>893b762b6e36d558df7ae6fccdfd8034f83a1c2e</Sha>
66
</Dependency>
7-
<Dependency Name="Microsoft.NET.ILLink.Tasks" Version="9.0.0-preview.2.24123.1" CoherentParentDependency="Microsoft.Dotnet.Sdk.Internal">
7+
<Dependency Name="Microsoft.NET.ILLink.Tasks" Version="9.0.0-preview.3.24129.2" CoherentParentDependency="Microsoft.Dotnet.Sdk.Internal">
88
<Uri>https://github.com/dotnet/runtime</Uri>
9-
<Sha>99b76018b6e4edc4ce185dd5f3c5697c6941d88e</Sha>
9+
<Sha>5e603d595e63ddc5cdce9777a40608279abdcc37</Sha>
1010
</Dependency>
11-
<Dependency Name="Microsoft.NETCore.App.Ref" Version="9.0.0-preview.2.24123.1" CoherentParentDependency="Microsoft.Dotnet.Sdk.Internal">
11+
<Dependency Name="Microsoft.NETCore.App.Ref" Version="9.0.0-preview.3.24129.2" CoherentParentDependency="Microsoft.Dotnet.Sdk.Internal">
1212
<Uri>https://github.com/dotnet/runtime</Uri>
13-
<Sha>99b76018b6e4edc4ce185dd5f3c5697c6941d88e</Sha>
13+
<Sha>5e603d595e63ddc5cdce9777a40608279abdcc37</Sha>
1414
</Dependency>
15-
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-9.0.100.Transport" Version="9.0.0-preview.2.24121.1" CoherentParentDependency="Microsoft.NETCore.App.Ref">
15+
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-9.0.100.Transport" Version="9.0.0-preview.3.24126.1" CoherentParentDependency="Microsoft.NETCore.App.Ref">
1616
<Uri>https://github.com/dotnet/emsdk</Uri>
17-
<Sha>2d3f1fe4807a21879cedba9d3fde8cd329fb17f2</Sha>
17+
<Sha>0f3e462442af5fe65271e3185d5b645ad40a6041</Sha>
1818
</Dependency>
19-
<Dependency Name="Microsoft.DotNet.Cecil" Version="0.11.4-alpha.24119.1" CoherentParentDependency="Microsoft.NET.ILLink.Tasks">
19+
<Dependency Name="Microsoft.DotNet.Cecil" Version="0.11.4-alpha.24120.1" CoherentParentDependency="Microsoft.NET.ILLink.Tasks">
2020
<Uri>https://github.com/dotnet/cecil</Uri>
21-
<Sha>61250b0ed403b3f9b69a33f7d8f66f311338d6a1</Sha>
21+
<Sha>0d0bc8e0f47fdae9834e1eac678f364c50946133</Sha>
2222
</Dependency>
2323
</ProductDependencies>
2424
<ToolsetDependencies>

eng/Versions.props

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<Project>
22
<!--Package versions-->
33
<PropertyGroup>
4-
<MicrosoftDotnetSdkInternalPackageVersion>9.0.100-preview.3.24126.2</MicrosoftDotnetSdkInternalPackageVersion>
5-
<MicrosoftNETILLinkTasksPackageVersion>9.0.0-preview.2.24123.1</MicrosoftNETILLinkTasksPackageVersion>
6-
<MicrosoftNETCoreAppRefPackageVersion>9.0.0-preview.2.24123.1</MicrosoftNETCoreAppRefPackageVersion>
4+
<MicrosoftDotnetSdkInternalPackageVersion>9.0.100-preview.3.24153.2</MicrosoftDotnetSdkInternalPackageVersion>
5+
<MicrosoftNETILLinkTasksPackageVersion>9.0.0-preview.3.24129.2</MicrosoftNETILLinkTasksPackageVersion>
6+
<MicrosoftNETCoreAppRefPackageVersion>9.0.0-preview.3.24129.2</MicrosoftNETCoreAppRefPackageVersion>
77
<MicrosoftDotNetApiCompatPackageVersion>7.0.0-beta.22103.1</MicrosoftDotNetApiCompatPackageVersion>
88
<MicrosoftDotNetBuildTasksFeedPackageVersion>7.0.0-beta.22103.1</MicrosoftDotNetBuildTasksFeedPackageVersion>
9-
<MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion>9.0.0-preview.2.24121.1</MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion>
9+
<MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion>9.0.0-preview.3.24126.1</MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion>
1010
<MicrosoftNETWorkloadEmscriptenPackageVersion>$(MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion)</MicrosoftNETWorkloadEmscriptenPackageVersion>
1111
<MicrosoftTemplateEngineTasksPackageVersion>7.0.100-rc.1.22410.7</MicrosoftTemplateEngineTasksPackageVersion>
12-
<MicrosoftDotNetCecilPackageVersion>0.11.4-alpha.24119.1</MicrosoftDotNetCecilPackageVersion>
12+
<MicrosoftDotNetCecilPackageVersion>0.11.4-alpha.24120.1</MicrosoftDotNetCecilPackageVersion>
1313
<SystemIOHashingPackageVersion>$(MicrosoftNETCoreAppRefPackageVersion)</SystemIOHashingPackageVersion>
1414
</PropertyGroup>
1515
<PropertyGroup>

external/Java.Interop

src/Microsoft.Android.Templates/android-activity/.template.config/template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "http://json.schemastore.org/template",
33
"author": "Microsoft",
44
"classifications": [ "Android", "Mobile" ],
5-
"name": "Android Activity template",
5+
"name": "Android Activity",
66
"description": "An Android Activity class",
77
"tags": {
88
"language": "C#",

0 commit comments

Comments
 (0)