Skip to content

Commit 6d98989

Browse files
sdzhongSimon Zhong
andauthored
Demo refresh (#188)
* Touch flagship error line * update APKs * update README --------- Co-authored-by: Simon Zhong <[email protected]>
1 parent f1fc0d2 commit 6d98989

File tree

6 files changed

+77
-156
lines changed

6 files changed

+77
-156
lines changed

README.md

Lines changed: 76 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,51 @@
11
# Android Demo
22

3-
This app demonstrates how to use Sentry in an Android application for capturing 4 types of exceptions:
3+
This app demonstrates how to use Sentry in an Android application:
44

5-
- Unhandled Exceptions (2)
5+
**Error Events**
6+
- Unhandled Exceptions
67
- Handled Exceptions
8+
- HTTP Client Errors
79
- Application Not Responding
810
- Native Crashes from C++ native code
911
- Message Capture
1012

11-
This app has all configuration (e.g. gradle) set to include Sentry SDK and ANR (Application Not Responding) and NDK (crash) events.
12-
13-
Sentry NDK libraries are used in addition to the Sentry SDK, for capturing errors and crashes in C++.
14-
15-
For use in **Production** see the [Official Sentry Android Documentation](https://docs.sentry.io/platforms/android/)
16-
Additional documentation:
17-
[ANR Configuration](https://docs.sentry.io/platforms/android/#configuration-options)
18-
[NDK Configuration](https://docs.sentry.io/platforms/android/#integrating-the-ndk)
13+
**Performance Issues**
14+
- DB on Main Thread
15+
- File IO on Main Thread
16+
- Image Decoding on Main Thread
17+
- Regex on Main Thread
18+
- JSON Decoding on Main Thread
19+
20+
**Tracing**
21+
- Time to Initial/Full Display
22+
- Automatic Instrumentation for UI Activity (UI Load, App Start Warm/Cold, Slow and Frozen Frames, OkHttp Library, File I/O Instrumentation, SQLite and Room query)
23+
- Manual Instrumentation
24+
- Profiling
25+
- CPU Usage, Memory
26+
27+
**Other**
28+
- Session Replay
29+
- Logs
30+
- Screenshots
31+
- View Hierary
32+
- User Feedback
1933

2034
## Versions
2135

2236
| dependency | version
2337
| ------------- |:-------------:|
24-
| sentry-java | 5.1.2 |
25-
| sentry-android-gradle-plugin | 3.0.0 |
26-
| Android Studio Arctic Fox | 2020.3.1 |
27-
| Gradle | 7.0.2 |
28-
| AVD | Nexus 5x API 29 x86, Pixel 2 API 29 |
29-
| sentry-cli | 1.55.1 |
30-
| macOS | Catalina 10.15.7 |
31-
| java | 16.0.2 |
32-
| jdk | 11.0.13 |
33-
34-
Do not use JDK 14
38+
| sentry-java | 8.17.0 |
39+
| sentry-android-gradle-plugin | 5.8.0 |
40+
| Android Studio Narwhal | 2025.1.1 Patch 1 |
41+
| Android Gradle Plugin | 8.6.0 (requires a minimum Gradle version of 8.7) |
42+
| sentry-cli | 2.44.0 |
43+
| macOS | Sequoia 15.5 |
44+
| OpenJDK supported, supported `java -version`:
3545
```
36-
which java
37-
/usr/bin/java
46+
openjdk version "21.0.2" 2024-01-16
47+
OpenJDK Runtime Environment Homebrew (build 21.0.2)
48+
OpenJDK 64-Bit Server VM Homebrew (build 21.0.2, mixed mode, sharing)
3849
```
3950

4051
## Setup
@@ -76,163 +87,73 @@ which java
7687
7788
## Run
7889
79-
1. `make all` if you haven't yet, or have made significant changes to your code. otherwise run the app.
90+
1. `make all` if you haven't yet, or have made significant changes to your code. Otherwise run the app.
8091
2. Run 'app' in Android Studio on an Android Virtual Device.
81-
82-
## What's Happening
83-
84-
### Errors
85-
86-
The MainActivity has 5 buttons that generate the following exception types:
87-
88-
1. **Unhandled Error + Attachment** of type Arithmetic Exception
89-
2. **Unhandled Error + Attachment** of type NegativeArraySizeException + Strips PII (removes user IP address in beforeSend)
90-
3. **Handled Error + Attachment** of type ArrayIndexOutOfBoundsException
91-
4. **ApplicationNotResponding (ANR)** Uses an infinite loop to crash the app after 5 seconds and reports event to Sentry.
92-
5. **Native Crash** of type SIGSEGV from native C++. The Sentry NDK sends this to Sentry.io for symbolication
93-
6. **Native Message** send custom event/message from native C++.
94-
95-
### Performance
96-
97-
The Android ToolStore demos the 2 classic toolstore transactions:
98-
1. **toolstore [android]** -
99-
* Is the ToolStore activity load triggered by clicking on the tools icon in the top header
100-
* The transaction creates spans for loading the activity UI elements, calling the `/tools` flask backend, and processing the response
101-
102-
2. **checkout [android]** -
103-
* Add some items to the cart by clicking `Add to Cart`
104-
* Start the checkout transaction by clicking on the shopping cart icon
105-
* The transaction contains 3 spans (including a call to the flask `/checkout` endpoint
106-
* The transaction generates 2 errors - one on the Android side `Exception:Failed to init delivery workflow` and the `Not enough inventory for wrench` exception on the backend.
107-
108-
![gif](screenshots/android_transactions.gif)
109-
110-
111-
## Android Native Crash: Missing Symbols for System Libraries
112-
113-
The Android team has added Android system symbol files to our built-in repositories (Add the new Android option in your project settings). If the native crash generated from your emulator is not fully symbolicated, this probably means our symbol server doesn't have the files relevant for your (virtual) device.
114-
In this case, you can fix that by updating Sentry's server. To do that:
115-
116-
1. Download the `Symbol Collector` app (**io.sentry.symbol.collector-Signed.apk**) which is available in the latest [release](https://github.com/getsentry/symbol-collector/releases/)
117-
2. Install it on to your emulator by drag-and-dropping the apk into the emulator screen.
118-
3. Run the Symbol Collector application
119-
4. Configure the target URL to transport the symbols to: `https://symbol-collector.services.sentry.io`
120-
5. Click `Collect Symbols`
121-
6. Once the transport completes, re-generate the crash.
122-
123-
## Release Health Testing
124-
Use two different devices (ie. two different android emulators). Keep one device crash free and one that has crashes so you can compare the crash free user rates.
125-
1. Select second device, different from the primary device you threw errors and crashes in
126-
2. Click Play/run
127-
3. Remember - do NOT click buttons and cause errors! you want to keep this one Crash Free. You could always make a new release if you want 100% crash free rates again.
128-
129-
1st device - errors, so you see Crash Free Rate go Down
130-
2nd device - sessions w/out errors, so if you keep creaitng healthy sessions, the nCrash Free Rate should go back up
131-
132-
ANR - click button, then start clicking on other areas of the screen. The second click (not the button click) is when it starts counting the seconds
133-
right when pop-up comes , event should be sent to Sentry. click 'close-up'.
134-
135-
See AndroidManifest.xml for different settings we tweak for demo's (e.g. default Session time, default ANR time
92+
3. Open the app, add items to cart, check out; open List App and click error-related buttons
93+
![demo](screenshots/demo.gif)
13694
13795
## How To Make a New Release
13896
13997
:warning: Only follow these steps when on the `master` branch, with no untracked git changes. This is necessary because we rely on these releases for our automated test data ("TDA") and don't want unintended local modifications (i.e. to DSNs or project names) to accidentally make it into our automated data. :warning:
14098
14199
### Part 1: Generate Release artifacts
142100
143-
1. **Increment both `versionName` and `versionCode` by 1 in `build.gradle`.** I.e. in the below example, we updated versionCode from `12` to `13` and versionName from `1.2.0` to `1.3.0`. Then run the app once so the executable gets this updated value.
144-
```
145-
defaultConfig {
146-
applicationId "com.example.vu.android"
147-
minSdkVersion 21
148-
targetSdkVersion 29
149-
versionCode 13
150-
versionName "1.3.0"
151-
}
152-
```
153-
154-
(This would make for a release of `1.3.0 (13) [email protected]+13`.)
101+
1. Checkout a new git branch.
102+
2. Run `./generate_release_artifacts.sh`, then run `./gradlew assembleRelease` to generate debug-build and release-build `.apk` files; copy them to the `/release` folder with `cp app/build/outputs/apk/release/app-release.apk ./release`
103+
3. Commit the changes to `build.gradle`, `app-release.apk`, and `app-debug.apk`.
104+
4. Push up the changes in a pull request.
105+
5. Get an approval and merge the changes.
155106
156-
2. **Run `./generate_release_artifacts.sh`, which generates debug-build and release-build `.apk` files.**
157-
3. **Checkout a new git branch (if your release version is 1.3.0, you can call the branch 1.3.0). Commit the changes to `build.gradle`, `app-release.apk`, and `app-debug.apk`.**
158-
4. **Push up the changes in a pull request.**
159-
5. **Get an approval and merge the changes.**
107+
### Part 2: Create the GitHub release
160108
161-
### Part 2: Create the Github release
162-
163-
1. After completing the steps in Part 1, and once your release branch is merged in, checkout the `master` branch and pull down the latest changes. Ensure your branch is clean (no untracked git changes).
164-
2. Run `./github_release.sh`, and select `y` when prompted.
165-
3. That's it. You'll see that a new release was created in https://github.com/sentry-demos/android/releases.
166-
4. You may need to restart your demo automation tools so they'll still hitting the latest APK release.
109+
(After completing the steps in Part 1, and once your release branch is merged in.)
110+
1. Run the Release GitHub Action https://github.com/sentry-demos/android/actions/workflows/release.yml, choose a version name and version code as prompted, then `Run workflow`.
111+
2. You'll see that a new release was created in https://github.com/sentry-demos/android/releases.
112+
3. Restart your demo automation tools so they'll still hitting the latest APK release.
167113
168114
### Other Notes on releases
169115
170116
The version code is unique. This is already part of build system in Android. The app won't compile without it.
171117
172118
Optional - Setting the release in AndroidManifest.xml will override what's set in src/build.gradle. Possible uses cases would be:
173-
1. indicating Paid vs Free versions of your apps
174-
2. match versionf for your Android and iOS apps together. force a release name.
175-
3. the pattern 'package@name+version' is new from Sentry, so you could override that in AndroidManifest.xml
119+
1. Indicating Paid vs Free versions of your apps
120+
2. Match versions for your Android and iOS apps together. force a release name.
121+
3. The pattern 'package@name+version' is new from Sentry, so you could override that in AndroidManifest.xml
176122
4. Good for testing if you're iterating quickly, but not publishing your app.
177123
```
178124
<meta-data android:name="io.sentry.release" android:value="[email protected]+1" />
179125
```
180126
181127
## How To Upgrade SDK
182-
1. increment sdk numbers in src/build.gradle like:
128+
1. Change to the latest Sentry Android Gradle Plugin as shown in https://docs.sentry.io/platforms/android/configuration/gradle/#setup:
129+
```
130+
plugins {
131+
id "com.android.application"
132+
id "io.sentry.android.gradle" version "5.8.0"
133+
}
134+
```
135+
2. Match the sdk_version from https://github.com/getsentry/sentry-android-gradle-plugin/blob/main/plugin-build/gradle.properties in src/build.gradle like:
183136
```
184-
implementation 'io.sentry:sentry-android:5.6.0'
185-
implementation 'io.sentry:sentry-android-okhttp:5.6.0'
186-
implementation 'io.sentry:sentry-android-fragment:5.6.0'
137+
implementation 'io.sentry:sentry-android:8.17.0'
187138
```
188-
2. Consider making a new Release
189-
3. click 'Sync Now' for sync'ing your gradle files in AndroidStudio
190-
4. `make all` will do a new `./gradlew build`
139+
Note: This step may not be necessary with newer versions of Sentry Android Gradle Plugin
191140
192-
## ANR
193-
Sometimes you'll see extra ANR events, because you have setting set to 3 seconds
194-
Hard to compare Total Number of Crashes to a report in Discover on handled:no and the release, because when a crash happens, you have to wait for the device to come back online again.
195-
There are some other technical reasons as well, which are still being sorted out.
196-
For instance, if you're ever filtering, sampling or Rate Limiting events/crashes out, then it's possible that the Sessions data isn ot getting filtered/sampled and so your Crash Free rate will appear higher than it actually is.
141+
3. Make a new Release
142+
4. Click 'Sync Now' for sync'ing your gradle files in AndroidStudio
143+
5. `make all` will do a new `./gradlew build`
197144
198145
## Sessions
199-
- if you put app to background, and put to foreground in less than 30seconds, it does not create new Session
200-
- if you put app to background, and wait more than 30seconds, then put to foreground, it will create new session
201-
- swiping up "close"", there's no way to know what happened to the Session. it's not a error/crash. it's a normal exited session.
202-
- opening the app again right away, should great a fresh new session
203-
- i write 30seconds here, but we set our default in AndroidManifest.xml to "3seconds" for demo purposes
204-
- if device has a stable connection, events sent right away
205-
- SentryServer has a pipeline that's queuing events, depends on state of Sentry
206-
- c++ crashes go through Symbolicator which has its own queuing and symbolication takes longer
207-
- need to restart the app
208-
- Session (ending) is sent when App goes to Background OR there's a crash
209-
- Session data is sent when Session Starts and when Session Ends
146+
- If you put app to background, then put to foreground within 30 seconds, it does not create new Session.
147+
- If you put app to background, then wait more than 30 seconds, then put to foreground, it will create new session.
148+
- 30 seconds is mentioned here, but we set our default in AndroidManifest.xml to 3 seconds (3000 millisecond) for demo purposes.
149+
- Swiping up "close", there's no way to know what happened to the session. It's not a error/crash. It's a normal exited session.
150+
- Opening the app again right away should great a fresh new session.
151+
- If device has a stable connection, events sent right away.
152+
- SentryServer has a pipeline that's queuing events, depends on state of Sentry.
153+
- C++ crashes go through Symbolicator which has its own queuing and symbolication takes slightly longer.
154+
- Need to restart the app.
155+
- Session (ending) is sent when App goes to Background OR there's a crash.
156+
- Session data is sent when Session Starts and when Session Ends.
210157
- So if you make a Handled Error, the Session data is not sent just yet. updates the session only locally in the device.
211-
212-
## Misc Knowledge
213-
- Release dashboard, open 1, 'All Issues' is issues across all the releases
214-
- Release dashboard, open 1, 'New Issue' sometimes not populating...
215-
- View Data in Discover if things aren't adding up / looking right in the Release Page
216-
- see Notion page on 'Crashes in SDKs and Product' for status updates on this stuff
217-
- `mechanism:signalHandler` comes from sentry-native and `mechanism:uncaughtException` comes from java/kotlin
218-
- Now (06/02/2020) ANR reported only if the pop-up comes up. doing 5seconds like Google does
219-
- When there's not a lot data yet, it's hard to calculate/show things.
220-
- Unique Users isn't the user's email, it's the Device. so in Discover could try things (but not working) like user.id, device.uuid, device. We didn't want to use sensitive data for Sessions. We generate a uuid for the user - Installation ID of the app on that device
221-
- Check Documentation, things may have changed.
222-
223-
## GIF Android Java Exception
224-
225-
![Android demo flow](android-demo.gif)
226-
227-
## GIF Android ANR
228-
229-
![Alt Text](android-demo-anr.gif)
230-
231-
## GIF Android Native Crash C++
232-
233-
![Native Crash](android-native-crash-take-1.gif)
234-
235-
## Troubleshooting
236-
If you're getting errors about "You need Java 11, not 1.8" and when you run `java --version` it says you're already on Java 11, then you may need to go into Android Studio Settings > Preferences > Build, Execution, Deployment > Gradle > Select jdk-11.
237-
238-
If youre app builds, compiles and starts to run but the AVD screen never appears and the Logcat is stuck on "E/GnssHAL_GnssInterface: gnssSvStatusCb: b: input svInfo.flags is", then you may need to disable Location and GPS services from your AVD. If you can't edit these settings on an existing AVD (as they're from the Hardware Profile), then create a new AVD and as you're doing that, go into the Hardware Profile settings and uncheck the box for GPS.
158+
- Difficult to compare crashes with a report in Discover (with `handled:no`) vs the Release because when a crash happens, you have to wait for the device to come back online again.
159+
- If you are ever filtering, sampling, or rate .imiting events/crashes out, then it's possible that the Sessions data isn't getting filtered/sampled and so your Crash Free Rate will appear higher than it actually is.

app-debug.apk

6.68 MB
Binary file not shown.

app-release.apk

1.15 MB
Binary file not shown.

app/src/main/java/com/example/vu/android/empowerplant/MainFragment.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ private void processDeliveryItem(ITransaction checkoutTransaction) {
424424
ISpan processDeliverySpan = checkoutTransaction.startChild("task", "process delivery");
425425

426426
try {
427-
throw new MainFragment.BackendAPIException("Failed to init delivery workflow");
427+
throw new MainFragment.BackendAPIException("Failed to init delivery workflow.");
428428
} catch (Exception e) {
429429
Log.e("processDeliveryItem", e.getMessage());
430430
processDeliverySpan.setThrowable(e);

release/app-release.apk

1.15 MB
Binary file not shown.

screenshots/demo.gif

5.53 MB
Loading

0 commit comments

Comments
 (0)