Flutter功能未定义插件stark的探索使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter功能未定义插件stark的探索使用

什么是Stark?

Stark 是一个为Dart开发者设计的轻量级依赖注入框架。它不依赖于Dart的反射API(mirrors),而是采用了基于工厂的方法,这提高了性能和实现的简易性。

快速开始

添加依赖

在您的Flutter或Dart项目中添加依赖:

dependencies:
  ...
  stark: 4.0.0

使用示例

导入stark

import 'package:stark/stark.dart';

定义模块

final appModule = {
    single((i) => Api()), 
    single<Repository>((i) => MyRepository(i.get())),
    factory((i) => UseCase(i.get())), 
    factoryWithParams((i, p) => ViewModel(i.get(), p["dynamicParam"])),
};

初始化Stark

//可以传递多个模块列表
Stark.init([
  appModule,
  domainModule,
  presentationModule
]);

带有日志记录器初始化:

Stark.init([...], logger: Logger());

获取注入实例

class LoginScreen extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => LoginScreenState();
}

class LoginScreenState extends State<LoginScreen>{
  final _loginViewModel = Stark.get<LoginViewModel>();

  @override
  Widget build(BuildContext context) {
    return Container(
      //...
    );
  }
}

单例定义

final myModule = {
    single((i) => Api(i.get())), 
};

带动态参数的单例:

final myModule = {
    singleWithParams((i,p) => Api(p["token"])), 
};

工厂定义

final myModule = {
    factory((i) => UseCase()), 
};

带动态参数的工厂:

final myModule = {
    factoryWithParams((i,p) => Api(p["token"])), 
};

命名注入

final myModule = {
    single((i) => Api(), named: "DEFAULT"), 
    single((i) => Api(), named: "EXTERNAL"), 
};

//获取命名注入
Stark.get<Api>(named: "DEFAULT");

动态参数

final myModule = {
    singleWithParams((i,p) => Api(p["token"])), 
    factoryWithParams((i,p) => MyPresenter(p["view"])), 
};

//获取带动态参数的实例
Stark.get<Api>(params: { "token" : "Bearer asdasdad"});
Stark.get<MyPresenter>(params: { "view" : this});

范围注入

你可以将类与Stark组件混合以关联注射生命周期到你的小部件:

class _MyHomePageState extends State<MyHomePage> with StarkComponent {
  ViewModel _viewModel;

  @override
  void initState() {
    super.initState();

    //视图模型实例将在该小部件状态调用dispose时被销毁。
    _viewModel = get<ViewModel>(
        params: <String, dynamic>{'name': 'Custom dynamic param'});
  }
  ...
}

可处理接口

当实现了可处理接口的注射被销毁时,会调用dispose方法,这对于ViewModel特别有用:

class LoginViewModel implements Disposable {
    @override
    dispose(){
      //当LoginViewModel被销毁时调用此方法,用于销毁RX主题或流。
    }
}

架构组件

为了支持不同的架构类型和状态管理,我们已将这些架构组件移动到新的库中:

  • stark_mvp: Stark库,适用于MVP架构
  • stark_bloc: Stark库,适用于flutter_bloc项目

示例代码

以下是一个完整的示例,演示了如何使用Stark进行依赖注入:

import 'package:flutter/material.dart';
import 'package:stark/stark.dart';

void main() => runApp(MyApp());

// API: 这里你可以使用Dio等库发起HTTP请求
class Api {
  Future<String> getText() async {
    await Future.delayed(const Duration(milliseconds: 500));
    return 'example Api async return';
  }
}

// Repository接口的实现
abstract class Repository {
  Future<String> getText();
}

// Repository的具体实现,注入了Api作为参数
class MyRepository implements Repository {
  MyRepository(this._api);
  final Api _api;

  @override
  Future<String> getText() async {
    final apiResult = await _api.getText();
    return apiResult;
  }
}

// Presenter的具体实现,注入了Repository作为参数
class Presenter  {
  Presenter(this._repository);

  final Repository _repository;

  Future<String> getText() async {
    final repositoryResult = await _repository.getText();
    return repositoryResult;
  }
}

class MyApp extends StatelessWidget {
  // 示例的Stark模块
  final module = {
    single((i) => Api()),
    single<Repository>((i) => MyRepository(i.get())),
    singleWithParams((i, p) => Presenter(i.get())),
  };

  @override
  Widget build(BuildContext context) {
    // 初始化Stark
    Stark.init([module], logger: Logger(level: Level.DEBUG));

    // 正常的Material App
    return MaterialApp(
      title: 'Stark Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Stark Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<StatefulWidget> createState() => _MyHomePageState();
}

class _MyHomePageState extends InjectableState<MyHomePage> {

  final presenter = Stark.get<Presenter>();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: FutureBuilder<String>(
          // 直接调用presenter
          future: presenter.getText(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Text(snapshot.data ?? '');
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

通过上述内容和示例代码,您可以了解如何在Flutter应用中使用Stark进行依赖注入,并根据需要调整和扩展其功能。希望这对您有所帮助!


更多关于Flutter功能未定义插件stark的探索使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter功能未定义插件stark的探索使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在探索使用未定义插件(如假定的 stark 插件)时,由于该插件不是官方或广泛认可的库,因此没有现成的文档或广泛使用的代码示例。不过,我们可以根据Flutter插件开发的一般流程来模拟如何集成和使用一个自定义插件。以下是一个假设性的示例,展示如何在Flutter项目中集成并使用一个自定义的原生插件(这里我们假设 stark 插件提供了某些原生功能)。

步骤 1: 创建 Flutter 插件项目

首先,你需要创建一个 Flutter 插件项目。这可以通过 Flutter 的命令行工具完成:

flutter create --template=plugin stark

这将创建一个名为 stark 的 Flutter 插件项目。

步骤 2: 实现原生功能

进入插件项目目录,并在 iosandroid 文件夹中实现原生功能。例如,假设 stark 插件提供了一个简单的原生方法 getGreeting,该方法返回一个问候字符串。

iOS 实现

ios/Classes/StarkPlugin.swift 中:

import Flutter

public class StarkPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterRegistrar) {
    let channel = FlutterMethodChannel(name: "stark_channel", binaryMessenger: registrar.messenger())
    let instance = StarkPlugin()
    channel.setMethodCallHandler(instance)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    if call.method == "getGreeting" {
      let greeting = "Hello from Stark Plugin!"
      result(greeting)
    } else {
      result(FlutterMethodNotImplemented)
    }
  }
}

Android 实现

android/src/main/kotlin/com/example/stark/StarkPlugin.kt 中:

package com.example.stark

import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import android.app.Activity

class StarkPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
  private lateinit var channel: MethodChannel

  override fun onAttachedToEngine(binding: FlutterPluginBinding) {
    channel = MethodChannel(binding.binaryMessenger, "stark_channel")
    channel.setMethodCallHandler(this)
  }

  override fun onMethodCall(call: MethodCall, result: Result) {
    if (call.method == "getGreeting") {
      val greeting = "Hello from Stark Plugin!"
      result.success(greeting)
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(binding: FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    // No-op for this plugin
  }

  override fun onDetachedFromActivityForConfigChanges(activity: Activity) {
    // No-op for this plugin
  }

  override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
    // No-op for this plugin
  }

  override fun onDetachedFromActivity(activity: Activity) {
    // No-op for this plugin
  }
}

步骤 3: 在 Flutter 项目中使用插件

现在,你可以在你的 Flutter 项目中引用并使用这个插件。

首先,将插件添加到你的 Flutter 项目的 pubspec.yaml 文件中(假设你已经将插件发布到本地或远程仓库):

dependencies:
  flutter:
    sdk: flutter
  stark:
    path: ../path/to/stark  # 如果是本地开发
    # 或者使用版本控制或包管理工具提供的路径

然后,在 Dart 代码中调用插件提供的方法:

import 'package:flutter/material.dart';
import 'package:stark/stark.dart';  // 假设插件提供了 stark.dart 文件

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  static const MethodChannel _channel = MethodChannel('stark_channel');

  Future<String?> _getGreeting() async {
    try {
      final String result = await _channel.invokeMethod('getGreeting');
      return result;
    } on PlatformException catch (e) {
      return 'Failed to get greeting: '${e.message}'.';
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Stark Plugin Demo'),
        ),
        body: Center(
          child: FutureBuilder<String?>(
            future: _getGreeting(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else if (snapshot.hasData) {
                  return Text('Greeting: ${snapshot.data!}');
                } else {
                  return Text('No greeting');
                }
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ),
      ),
    );
  }
}

请注意,上述代码是基于假设的 stark 插件提供的 getGreeting 方法。在实际使用中,你需要根据 stark 插件的实际 API 和功能进行调整。由于 stark 插件不是官方或广泛认可的库,因此具体的实现和用法可能会有所不同。

回到顶部