-
Notifications
You must be signed in to change notification settings - Fork 132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modularization prototype. #1
Conversation
@@ -0,0 +1,21 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.idea files are generated by Android Studio and can be a pain to share between developers.
In azme we git ignored them, worked great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IDE related files shouldn't be there. BTW Guillaume, it is not simply opening up project folder, need to be imported. There is a Gradle task that can generate IDE related stuffs so we can do this instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I just used Githubs default .gitignore instead of the one we already used. I removed the .idea and updated the gitignore.
Shouldn't we rely only on the stable version of the android tools? I get Error:Failed to find Build Tools revision 24.0.0-rc4 when trying to open the project. For an open source SDK we should have that design constraint: download latest stable android studio,next, next, checkout from sources: it just works with no warning and no error. |
Sure. From: Guillaume Perrot notifications@github.com Shouldn't we rely only on the stable version of the android tools? I get Error:Failed to find Build Tools revision 24.0.0-rc4 when trying to open the project. — |
minifyEnabled false | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have duplicated settings in build.gradle files. You can change the constants to variables and then set the variables in root build.gradle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
Question is: how do you want/expect me/us to handle this sort of stuff? Should we discuss here or F2F?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No lintOptions and checkstyle (e.g. jacoco) here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add lintoptions and use checkstyle.
I’m also a fan of Findbugs and was looking at infer (http://fbinfer.com/) the other day.
This is sort of a comment: I haven't said this excplicitly (at least I think) but I'd love to refactor as much of the stuff that's inside the CrashManager as possible. This is old old old old stuff. |
That's how we worked so far, too. |
|
||
android { | ||
compileSdkVersion 23 | ||
buildToolsVersion "24.0.0-rc4" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also use 23.0.3 like in other modules. We should not depend on rc/preview tools for open source product code.
All modules should use the same stable compileSdkVersion, buildToolsVersion. For bundling reasons those also have to target the same minSdkVersion and targetSdkVersion. It also makes sense for now to make them have all the same versionCode (which is ignored for libraries anyway) and versionName.
Adds a crash button which forces an app crash. Sets up the SDK in automatic-mode.
dependencies { | ||
compile fileTree(dir: 'libs', include: ['*.jar']) | ||
compile 'com.android.support:appcompat-v7:23.4.0' | ||
testCompile 'junit:junit:4.12' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this module for unit test or integration test?
Need to have unittest in each module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this module is a “test” app that integrates the other two modules. Like your “puppet” app.
We can use a different approach, if you want. FYI: We’ve had a separate. app quick (manual) for integration tests for HockeyApp but I kinda like the approach of having a quick way of testing if my recent change works.
About unit tests: yes, I think each module should contain unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it needs to be renamed to avoid any confusions. :) I'd prefer an actual app name instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. IMHO it’d be best if we name the app the same across all plattforms.
I hereby propose “Sasquatch” or “St.Bernard” to fit with the Avalanche theme ;)
Hi, I like the structure of the SDK. Good starting point / great work! Also the iOS project structure aligns with that perfectly. Some things that we should discuss.
Thank you! |
About the naming, I discussed about that with Matt on our channel and we can't use "Avalanche". He proposed the simple "Xamarin" for now as it needs to be really explicit because directly used by customers. |
@chrwend
@clpolet |
Avalanche is an internal naming and can't be used for public facing code, at least that's what I've heard. This is definitively a PM discussion. |
@TroubleMakerBen I'm also fine with module names like Crashes, Metrics, Push for Android. Regarding the class methods I'm pretty sure there would be a way to inject a mock which acts as the shared instance for your tests. But, yeah... |
The main intention to go with a singleton approach with getInstance() rather than static class methods was that this makes it easier to change the API down the road, if we'd like to remove the singleton patterns and it makes the whole project and it's modules easier to test in isolation. |
Update
|
Also add missing abstract keyword for ingestion models.
Fix coverage for firebase/push
…onapp Customvision app + Assets module
This PR is based on the work done by @ranterle in https://github.com/bitstadium/HockeySDK-Android-Private/pull/19 and I shamelessly copied Mat's explanation of how the SDK works
It's a base for our architecture discussions for the SDK.
Please have a look and discuss.
Disclaimer
Treat this as WIP and as a long running PR. This is just an idea that I wanted to get out there for us to discuss, we're by no means bound to any of this. I hope I ticked all the right label boxes to make this look like the crazy 🎄 that it is.
What do we have here?
This approach contains several concepts which are not easy to build without each other, that's why I included them in one massive PR.
Avalanche
classModularization
First of all, this splits up the SDK into several sub-modules, basically one per feature.
It adds a [core-module]((https://github.com/Microsoft/AvalancheSDK-Android/blob/modular-prototype/avalanchesdk-core) which is meant to provide all kind of centralized services: Setup, module management & communication, logging, persistence, transmission pipeline, shared resources & strings, …
The rest of the features will be implemented through different modules, e.g. the hockeysdk-crash module.
Telling modules apart
Modules live in their own namespace. Where the core is in
com.microsoft.android
, the crash module for example lives incom.microsoft.android.crash
. This is both reflected in the Java package structure, but also in the Android resource bundling structure. Otherwise the modules would conflict over shared and individual resources. See the relevant Java packages and AndroidManifest.xml files for example.Module implementation - example: CrashManager
Next, each module means to be converted from the static class method access (which was horrible for testing/mocking and more) to singletons. As an example take the new CrashManager. It has been fully converted. It would even be possible to remove the need for the modules to be singletons - but that I left up for discussion on purpose (who doesn't love a fight over singletons) and it would have taken this one step too far.
Integration
Bringing it all together is a new approach in integration. Kudos to @troublemakerben for his work on the umbrella header on Android. This is somewhat similar.
Why not start with an example? Here you go:
For the brutally simplest way of integration you pull in your dependencies, and then at the earliest stage in your app call this:
This will then detect all available features (for example if you have crash reporting and update distribution as dependencies, it will find both) and automatically instantiate and configure them.
A bit more flexible? How about:
This will only try to instantiate and configure the crash reporting feature, even if other modules would be available. It will still do auto-configuration for the modules you defined.
Want even more flexibility?
This will only configure the SDK with the features in the way you configured them. No auto-configuration will be performed, since you are doing this inline.
You can also do:
and then later
This will only set up the SDK in the first step and then allow you to add in the configured features where you need them.
Auto-Configuration?!
What does that mean? So as the integration, all modules will have an opinion on how they typically should integrate with the app. For example for the crash manager it makes sense to register and configure it in the
onResume()
callback of the app's main activity.To achieve this, all features (or components) need to do two things:
getInstance()
which returns an instance of the class - this is a convention defined by theAvalanche
class.AvalancheComponent
interface or subclass the convenience classDefaultAvalancheComponent
.Because of this, they can hook into the application/activity lifecycle and perform their own registration when they see fit. They are responsible of respecting the users preference, e.g. when the user already configured the feature otherwise, they should reflect that. For an example see the registration code for the crash manager.