239 lines
6.3 KiB
Markdown
239 lines
6.3 KiB
Markdown
# Coding Conventions
|
||
|
||
**Analysis Date:** 2026-03-30
|
||
|
||
## Naming Patterns
|
||
|
||
**Files:**
|
||
- Dart: lowercase with underscores (`arc.dart`, `arc_platform_interface.dart`, `arc_method_channel.dart`)
|
||
- Java: PascalCase matching class name (`ArcPlugin.java`, `FaceEngineManager.java`)
|
||
|
||
**Classes:**
|
||
- PascalCase: `Arc`, `ArcPlatform`, `MethodChannelArc`, `FaceEngineManager`, `FaceErrorCode`
|
||
|
||
**Methods/Functions:**
|
||
- camelCase: `getPlatformVersion`, `activeOnline`, `detectFaces`, `extractFaceFeature`
|
||
|
||
**Variables:**
|
||
- Private Dart members: underscore prefix (`_token`, `_instance`, `_isDetecting`)
|
||
- Java: `private` keyword with camelCase: `faceEngine`, `isInitialized`, `lastRgbLiveness`
|
||
|
||
**Constants:**
|
||
- Dart: `static final` with underscore for private: `static final Object _token = Object();`
|
||
- Java enum: uppercase with underscores: `MOK`, `MERR_UNKNOWN`, `ENGINE_NOT_INITIALIZED`
|
||
|
||
## Code Style
|
||
|
||
**Formatting:**
|
||
- Dart: `flutter_lints ^5.0.0` via `analysis_options.yaml`
|
||
- Config: `include: package:flutter_lints/flutter.yaml`
|
||
- Java: Standard Android/Java conventions
|
||
|
||
**Linting:**
|
||
- Dart: flutter_lints package rules
|
||
- Java: No explicit linting config detected
|
||
|
||
## Import Organization
|
||
|
||
**Dart Order:**
|
||
1. SDK imports (`dart:typed_data`)
|
||
2. Package imports (`package:plugin_platform_interface/plugin_platform_interface.dart`)
|
||
3. Relative imports (`arc_method_channel.dart`)
|
||
|
||
**Example:**
|
||
```dart
|
||
import 'dart:typed_data';
|
||
|
||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||
|
||
import 'arc_method_channel.dart';
|
||
```
|
||
|
||
**Java Order:**
|
||
1. Package declaration
|
||
2. Android SDK imports
|
||
3. Third-party imports
|
||
4. JUnit/Mockito imports (in tests)
|
||
|
||
## Error Handling
|
||
|
||
**Dart Patterns:**
|
||
- Platform interface throws `UnimplementedError` for abstract methods:
|
||
```dart
|
||
Future<String?> getPlatformVersion() {
|
||
throw UnimplementedError('platformVersion() has not been implemented.');
|
||
}
|
||
```
|
||
- Method channel calls wrapped in try-catch with `PlatformException`
|
||
- Return `Map<String, dynamic>?` with `success`, `errorCode`, `message` keys
|
||
|
||
**Java Patterns:**
|
||
- Parameter validation before processing
|
||
- Error codes via `FaceErrorCode` enum
|
||
- Result Map with consistent keys: `success`, `errorCode`, `message`
|
||
- Logging with `android.util.Log.e()` for errors
|
||
|
||
**Return Format:**
|
||
All API methods return consistent Map structure:
|
||
```dart
|
||
{
|
||
'success': bool, // Operation success status
|
||
'errorCode': int, // Error code (0 = success)
|
||
'message': String, // Error/success message
|
||
// Additional data keys based on method
|
||
}
|
||
```
|
||
|
||
## Documentation
|
||
|
||
**Dart Comments:**
|
||
- Triple-slash `///` for method documentation
|
||
- Chinese descriptions required
|
||
- Parameter documentation: `[paramName] description`
|
||
- Return documentation after parameters
|
||
|
||
**Example:**
|
||
```dart
|
||
/// 激活 SDK(在线激活)
|
||
/// [appId] 应用 ID(从虹软控制台获取)
|
||
/// [sdkKey] SDK 密钥(从虹软控制台获取)
|
||
/// [activeKey] 激活密钥
|
||
/// 返回包含 success, errorCode, message 的 Map
|
||
Future<Map<String, dynamic>?> activeOnline({
|
||
required String appId,
|
||
required String sdkKey,
|
||
required String activeKey,
|
||
})
|
||
```
|
||
|
||
**Java Comments:**
|
||
- Javadoc `/** */` format
|
||
- `@param` and `@return` tags
|
||
- Chinese descriptions
|
||
|
||
**Example:**
|
||
```java
|
||
/**
|
||
* 激活 SDK(在线激活方式)
|
||
* @param context Android 上下文
|
||
* @param appId 应用 ID(从虹软控制台获取)
|
||
* @param sdkKey SDK 密钥(从虹软控制台获取)
|
||
* @param activeKey 激活密钥
|
||
* @return 错误码(0 表示成功)
|
||
*/
|
||
public int activeOnline(Context context, String appId, String sdkKey, String activeKey)
|
||
```
|
||
|
||
## Logging
|
||
|
||
**Dart:**
|
||
- `debugPrint()` for development logging
|
||
- Located in: `example/lib/main.dart`
|
||
|
||
**Java:**
|
||
- `android.util.Log.i()` for info
|
||
- `android.util.Log.e()` for errors
|
||
- `android.util.Log.w()` for warnings
|
||
- Tag: `"FaceEngineManager"`
|
||
|
||
**Example:**
|
||
```java
|
||
android.util.Log.i("FaceEngineManager", "引擎初始化成功!");
|
||
android.util.Log.e("FaceEngineManager", "引擎初始化失败,错误码: " + result);
|
||
```
|
||
|
||
## Function Design
|
||
|
||
**Parameters:**
|
||
- Dart: Named parameters with `required` keyword
|
||
- Optional parameters have default values
|
||
|
||
**Example:**
|
||
```dart
|
||
Future<Map<String, dynamic>?> detectFaces({
|
||
required Uint8List data,
|
||
required int width,
|
||
required int height,
|
||
int format = 2050, // Optional with default
|
||
})
|
||
```
|
||
|
||
**Return Values:**
|
||
- All async methods return `Future<Map<String, dynamic>?>`
|
||
- Null-safe with nullable type annotation `?`
|
||
|
||
## Module Design
|
||
|
||
**Platform Interface Pattern:**
|
||
- Abstract class extends `PlatformInterface`
|
||
- Static instance getter/setter
|
||
- Token verification for platform registration
|
||
|
||
**Example Structure:**
|
||
```dart
|
||
abstract class ArcPlatform extends PlatformInterface {
|
||
ArcPlatform() : super(token: _token);
|
||
static final Object _token = Object();
|
||
static ArcPlatform _instance = MethodChannelArc();
|
||
static ArcPlatform get instance => _instance;
|
||
static set instance(ArcPlatform instance) {
|
||
PlatformInterface.verifyToken(instance, _token);
|
||
_instance = instance;
|
||
}
|
||
}
|
||
```
|
||
|
||
**Method Channel Implementation:**
|
||
- Class extends platform interface
|
||
- `@visibleForTesting` annotation for test exposure
|
||
- Method channel with constant name: `'arc'`
|
||
|
||
**Singleton Pattern (Java):**
|
||
```java
|
||
public class FaceEngineManager {
|
||
private static FaceEngineManager instance;
|
||
private FaceEngineManager() {}
|
||
public static synchronized FaceEngineManager getInstance() {
|
||
if (instance == null) {
|
||
instance = new FaceEngineManager();
|
||
}
|
||
return instance;
|
||
}
|
||
}
|
||
```
|
||
|
||
## State Management
|
||
|
||
**Flutter Widget State:**
|
||
- Private state variables with underscore prefix
|
||
- `StatefulWidget` with corresponding `State` class
|
||
- `mounted` check before `setState`
|
||
|
||
**Example:**
|
||
```dart
|
||
class _HomePageState extends State<HomePage> {
|
||
String _platformVersion = 'Unknown';
|
||
bool _isActivated = false;
|
||
|
||
if (!mounted) return;
|
||
setState(() {
|
||
_platformVersion = platformVersion;
|
||
});
|
||
}
|
||
```
|
||
|
||
## Key Files
|
||
|
||
**Core Dart Files:**
|
||
- `lib/arc.dart` - Main API class
|
||
- `lib/arc_platform_interface.dart` - Abstract platform interface
|
||
- `lib/arc_method_channel.dart` - Method channel implementation
|
||
|
||
**Core Java Files:**
|
||
- `android/src/main/java/com/xiarui/arc/ArcPlugin.java` - Flutter plugin entry
|
||
- `android/src/main/java/com/xiarui/arc/FaceEngineManager.java` - Engine singleton
|
||
- `android/src/main/java/com/xiarui/arc/FaceErrorCode.java` - Error code enum
|
||
|
||
---
|
||
|
||
*Convention analysis: 2026-03-30* |