Skip to content

Commit 3ce1d7d

Browse files
authored
Feat/example (#5)
1 parent 9746be3 commit 3ce1d7d

File tree

14 files changed

+231
-9
lines changed

14 files changed

+231
-9
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ jobs:
4444
- name: Test
4545
run: flutter test
4646
- name: Build ${{ matrix.target }}
47+
env:
48+
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
4749
run: |
4850
cd example
4951
TARGET=${{ matrix.target }}
@@ -62,7 +64,7 @@ jobs:
6264
runs-on: ubuntu-latest
6365
steps:
6466
- uses: actions/checkout@v2
65-
- uses: axel-op/dart-package-analyzer@v2
67+
- uses: axel-op/dart-package-analyzer@v3
6668
id: analysis
6769
with:
6870
githubToken: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
*.iml
88

99
build/
10+
.cxx/

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ Sentry SDK for Flutter
1313
This is a work in progress.
1414
A lot still to be done on [the base SDK](http://github.com/getsentry/sentry-dart) before the proper Flutter support is shipped.
1515

16+
## Contributing
17+
18+
The SDK currently supports Android, iOS and Web. We build the example app for these targets in 3 platforms: Windows, macOS and Linux.
19+
This is to make sure you'd be able to contribute to this project if you're using any of these operating systems.
20+
21+
We also run CI against the Flutter `stable` and `beta` channels so you should be able to build it if you're in one of those.
22+
23+
### Dependencies
24+
25+
* Android: Android SDK with NDK: The example project includes C++.
26+
* iOS: You'll need a Mac with xcode installed.
27+
* Web: No additional dependencies.
28+
1629
## Resources
1730

1831
* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/dotnet/)

android/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ android {
3939
}
4040

4141
dependencies {
42+
api 'io.sentry:sentry-android:2.3.0'
4243
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
4344
}

example/android/app/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
cmake_minimum_required(VERSION 3.6)
2+
project(sentry-sample LANGUAGES C CXX)
3+
4+
add_library(native-sample SHARED src/main/cpp/native-sample.cpp)
5+
6+
find_library(LOG_LIB log)
7+
8+
include (${ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK})
9+
10+
target_link_libraries(
11+
native-sample PRIVATE
12+
${LOG_LIB}
13+
${ANDROID_GRADLE_NATIVE_MODULES}
14+
)

example/android/app/build.gradle

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,19 @@ if (flutterVersionName == null) {
2424
apply plugin: 'com.android.application'
2525
apply plugin: 'kotlin-android'
2626
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27+
apply plugin: 'com.ydq.android.gradle.native-aar.import'
28+
apply plugin: 'io.sentry.android.gradle'
2729

2830
android {
29-
compileSdkVersion 28
31+
compileOptions {
32+
sourceCompatibility = JavaVersion.VERSION_1_8
33+
targetCompatibility = JavaVersion.VERSION_1_8
34+
}
35+
kotlinOptions {
36+
jvmTarget = JavaVersion.VERSION_1_8
37+
}
38+
39+
compileSdkVersion 29
3040

3141
sourceSets {
3242
main.java.srcDirs += 'src/main/kotlin'
@@ -39,9 +49,26 @@ android {
3949
defaultConfig {
4050
applicationId "io.sentry.flutter.example"
4151
minSdkVersion 16
42-
targetSdkVersion 28
52+
targetSdkVersion 29
4353
versionCode flutterVersionCode.toInteger()
4454
versionName flutterVersionName
55+
56+
externalNativeBuild {
57+
cmake {
58+
arguments.add(0, "-DANDROID_STL=c++_static")
59+
}
60+
}
61+
62+
ndk {
63+
abiFilters("x86", "armeabi-v7a", "x86_64", "arm64-v8a")
64+
}
65+
}
66+
ndkVersion "21.3.6528147"
67+
68+
externalNativeBuild {
69+
cmake {
70+
setPath("CMakeLists.txt")
71+
}
4572
}
4673

4774
buildTypes {
@@ -57,4 +84,12 @@ flutter {
5784

5885
dependencies {
5986
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
87+
implementation 'androidx.work:work-runtime:2.4.0'
88+
implementation 'androidx.work:work-runtime-ktx:2.4.0'
89+
implementation "androidx.annotation:annotation:1.1.0"
90+
}
91+
92+
sentry {
93+
uploadNativeSymbols true
94+
includeNativeSources true
6095
}

example/android/app/src/main/AndroidManifest.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,22 @@
4242
<category android:name="android.intent.category.LAUNCHER"/>
4343
</intent-filter>
4444
</activity>
45+
<!-- In order to capture crashes caused by the native layer early during Init.
46+
This is relevant for errors that happen before Flutter runs far enough to run init -->
47+
<meta-data
48+
android:name="io.sentry.dsn"
49+
android:value="https://[email protected]/2078115" />
50+
<meta-data
51+
android:name="io.sentry.debug"
52+
android:value="true" />
53+
<!-- Will be enabled by default from version 3.0 -->
54+
<meta-data
55+
android:name="io.sentry.session-tracking.enable"
56+
android:value="true" />
57+
<!-- To quickly demonstrate the ANR capture. Default is 5 seconds. -->
58+
<meta-data
59+
android:name="io.sentry.anr.timeout-interval-mills"
60+
android:value="2000" />
4561
<!-- Don't delete the meta-data below.
4662
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
4763
<meta-data
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <jni.h>
2+
#include <android/log.h>
3+
#include <sentry.h>
4+
5+
#define TAG "sentry-sample"
6+
7+
extern "C" {
8+
9+
JNIEXPORT void JNICALL Java_io_sentry_flutter_example_MainActivity_crash(JNIEnv *env, jclass cls) {
10+
__android_log_print(ANDROID_LOG_WARN, TAG, "About to crash with a SEGFAULT in C++!");
11+
char *ptr = 0;
12+
*ptr += 1;
13+
}
14+
15+
JNIEXPORT void JNICALL Java_io_sentry_flutter_example_MainActivity_message(JNIEnv *env, jclass cls) {
16+
// __android_log_print(ANDROID_LOG_WARN, TAG, "Sending message.");
17+
sentry_value_t event = sentry_value_new_message_event(
18+
/* level */ SENTRY_LEVEL_INFO,
19+
/* logger */ "native",
20+
/* message */ "message from C++!"
21+
);
22+
sentry_capture_event(event);
23+
}
24+
25+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,68 @@
11
package io.sentry.flutter.example
22

3+
import android.content.Context
4+
import androidx.annotation.NonNull
5+
import androidx.work.*
36
import io.flutter.embedding.android.FlutterActivity
7+
import io.flutter.embedding.engine.FlutterEngine
8+
import io.flutter.plugin.common.MethodChannel
9+
import io.sentry.core.Sentry
410

511
class MainActivity: FlutterActivity() {
12+
private val _channel = "example.flutter.sentry.io"
13+
14+
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
15+
super.configureFlutterEngine(flutterEngine)
16+
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, _channel).setMethodCallHandler {
17+
call, result ->
18+
// Note: this method is invoked on the main thread.
19+
when (call.method) {
20+
"throw" -> {
21+
throw Exception("Thrown from Kotlin!")
22+
}
23+
"background" -> {
24+
WorkManager.getInstance(this)
25+
.enqueue(OneTimeWorkRequestBuilder<BrokenWorker>()
26+
.build())
27+
}
28+
"anr" -> {
29+
Thread.sleep(6_000)
30+
}
31+
"capture" -> {
32+
try {
33+
throw RuntimeException("Catch this exception!")
34+
} catch (e: Exception) {
35+
Sentry.captureException(e);
36+
}
37+
}
38+
"crash" -> {
39+
crash();
40+
}
41+
"native_capture_message" -> {
42+
message();
43+
}
44+
else -> {
45+
result.notImplemented()
46+
}
47+
}
48+
}
49+
}
50+
51+
external fun crash(): Unit?
52+
external fun message(): Unit?
53+
54+
companion object {
55+
init {
56+
System.loadLibrary("native-sample")
57+
}
58+
}
59+
60+
class BrokenWorker(appContext: Context, workerParams: WorkerParameters): Worker(appContext, workerParams)
61+
{
62+
override fun doWork(): Result
63+
{
64+
throw RuntimeException("Kotlin background task")
65+
return Result.success()
66+
}
67+
}
668
}

example/android/build.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
buildscript {
2-
ext.kotlin_version = '1.3.50'
2+
ext.kotlin_version = '1.4.0'
33
repositories {
44
google()
55
jcenter()
6+
mavenCentral()
67
}
78

89
dependencies {
10+
classpath 'io.sentry:sentry-android-gradle-plugin:1.7.35'
911
classpath 'com.android.tools.build:gradle:3.5.0'
1012
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13+
classpath 'com.ydq.android.gradle.build.tool:nativeBundle:1.0.6'
1114
}
1215
}
1316

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Fri Jun 23 08:50:38 CEST 2017
1+
#Mon Aug 24 18:39:28 EDT 2020
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

example/android/sentry.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
defaults.project=flutter
2+
defaults.org=sentry-test
3+
#auth.token= set in the file ~/.sentryclirc with the content:
4+
#[auth]
5+
#token=528be1f...

example/lib/main.dart

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,55 @@ class _MyAppState extends State<MyApp> {
156156
null)
157157
}),
158158
RaisedButton(
159-
child: const Text('Platform: MethodChannel unknown method'),
159+
child: const Text('Platform: unknown MethodChannel'),
160160
onPressed: () async {
161-
const channel = MethodChannel('method_channel');
161+
const channel = MethodChannel('unknown');
162162
await channel.invokeMethod<void>('unknown');
163163
},
164164
),
165+
RaisedButton(
166+
child: const Text('Platform: Throw Exception'),
167+
onPressed: () async {
168+
const channel = MethodChannel('example.flutter.sentry.io');
169+
await channel.invokeMethod<void>('throw');
170+
},
171+
),
172+
RaisedButton(
173+
child: const Text('Platform: Background error'),
174+
onPressed: () async {
175+
const channel = MethodChannel('example.flutter.sentry.io');
176+
await channel.invokeMethod<void>('background');
177+
},
178+
),
179+
RaisedButton(
180+
child: const Text('Platform: try/catch/capture'),
181+
onPressed: () async {
182+
const channel = MethodChannel('example.flutter.sentry.io');
183+
await channel.invokeMethod<void>('capture');
184+
},
185+
),
186+
RaisedButton(
187+
child: const Text('Platform: ANR'),
188+
onPressed: () async {
189+
const channel = MethodChannel('example.flutter.sentry.io');
190+
await channel.invokeMethod<void>('anr');
191+
},
192+
),
193+
RaisedButton(
194+
child: const Text('Platform: native crash (signal)'),
195+
onPressed: () async {
196+
const channel = MethodChannel('example.flutter.sentry.io');
197+
await channel.invokeMethod<void>('crash');
198+
},
199+
),
200+
// XXX: Show only relevant buttons for the platform
201+
RaisedButton(
202+
child: const Text('Platform: native capture message'),
203+
onPressed: () async {
204+
const channel = MethodChannel('example.flutter.sentry.io');
205+
await channel.invokeMethod<void>('native_capture_message');
206+
},
207+
),
165208
],
166209
),
167210
),

example/run.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ if [ "$1" == "ios" ]; then
1919
elif [ "$1" == "android" ]; then
2020
flutter build apk --dart-define=SENTRY_RELEASE=$SENTRY_RELEASE --split-debug-info=symbols --obfuscate
2121
adb install build/app/outputs/flutter-apk/app-release.apk
22+
adb shell am start -n io.sentry.flutter.example/io.sentry.flutter.example.MainActivity
2223
echo -e "[\033[92mrun\033[0m] Android app installed"
2324
elif [ "$1" == "web" ]; then
2425
# Uses dart2js
@@ -54,6 +55,7 @@ if [ "$1" == "web" ]; then
5455
popd
5556
else
5657
echo -e "[\033[92mrun\033[0m] Uploading debug information files"
57-
sentry-cli upload-dif --org $SENTRY_ORG --project $SENTRY_PROJECT symbols
58+
# directory 'symbols' contain the Dart debug info files but to include platform ones, use current dir.
59+
sentry-cli upload-dif --org $SENTRY_ORG --project $SENTRY_PROJECT .
5860
fi
5961

0 commit comments

Comments
 (0)