flutter和安卓通信(官方代码)
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(FlutterView()); } class FlutterView extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter View', theme: ThemeData( primarySwatch: Colors.grey, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { static const String _channel = 'increment'; static const String _pong = 'pong'; static const String _emptyMessage = ''; static const BasicMessageChannel<String> platform = BasicMessageChannel<String>(_channel, StringCodec()); int _counter = 0; @override void initState() { super.initState(); platform.setMessageHandler(_handlePlatformIncrement); } Future<String> _handlePlatformIncrement(String message) async { setState(() { _counter++; }); return _emptyMessage; } void _sendFlutterIncrement() { platform.send(_pong); } @override Widget build(BuildContext context) { return Scaffold( body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Expanded( child: Center( child: Text( 'Platform button tapped $_counter time${ _counter == 1 ? '' : 's' }.', style: const TextStyle(fontSize: 17.0)), ), ), Container( padding: const EdgeInsets.only(bottom: 15.0, left: 5.0), child: Row( children: <Widget>[ Image.asset('assets/flutter-mark-square-64.png', scale: 1.5), const Text('Flutter', style: TextStyle(fontSize: 30.0)), ], ), ), ], ), floatingActionButton: FloatingActionButton( onPressed: _sendFlutterIncrement, child: const Icon(Icons.add), ), ); } }
name: flutter_view description: A new flutter project. environment: # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. sdk: ">=2.0.0-dev.68.0 <3.0.0" dependencies: flutter: sdk: flutter characters: 1.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.15.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.3.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true assets: - assets/flutter-mark-square-64.png # PUBSPEC CHECKSUM: e9aa
public class MainActivity extends AppCompatActivity { private static FlutterEngine flutterEngine; private FlutterView flutterView; private int counter; private static final String CHANNEL = "increment"; private static final String EMPTY_MESSAGE = ""; private static final String PING = "ping"; private BasicMessageChannel<String> messageChannel; private String[] getArgsFromIntent(Intent intent) { // Before adding more entries to this list, consider that arbitrary // Android applications can generate intents with extra data and that // there are many security-sensitive args in the binary. ArrayList<String> args = new ArrayList<>(); if (intent.getBooleanExtra("trace-startup", false)) { args.add("--trace-startup"); } if (intent.getBooleanExtra("start-paused", false)) { args.add("--start-paused"); } if (intent.getBooleanExtra("enable-dart-profiling", false)) { args.add("--enable-dart-profiling"); } if (!args.isEmpty()) { String[] argsArray = new String[args.size()]; return args.toArray(argsArray); } return null; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] args = getArgsFromIntent(getIntent()); if (flutterEngine == null) { flutterEngine = new FlutterEngine(this, args); flutterEngine.getDartExecutor().executeDartEntrypoint( DartEntrypoint.createDefault() ); } setContentView(R.layout.flutter_view_layout); ActionBar supportActionBar = getSupportActionBar(); if (supportActionBar != null) { supportActionBar.hide(); } flutterView = findViewById(R.id.flutter_view); flutterView.attachToFlutterEngine(flutterEngine); messageChannel = new BasicMessageChannel<>(flutterEngine.getDartExecutor(), CHANNEL, StringCodec.INSTANCE); messageChannel. setMessageHandler(new MessageHandler<String>() { @Override public void onMessage(String s, Reply<String> reply) { onFlutterIncrement(); reply.reply(EMPTY_MESSAGE); } }); FloatingActionButton fab = findViewById(R.id.button); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendAndroidIncrement(); } }); } private void sendAndroidIncrement() { messageChannel.send(PING); } private void onFlutterIncrement() { counter++; TextView textView = findViewById(R.id.button_tap); String value = "Flutter button tapped " + counter + (counter == 1 ? " time" : " times"); textView.setText(value); } @Override protected void onResume() { super.onResume(); flutterEngine.getLifecycleChannel().appIsResumed(); } @Override protected void onPause() { super.onPause(); flutterEngine.getLifecycleChannel().appIsInactive(); } @Override protected void onStop() { super.onStop(); flutterEngine.getLifecycleChannel().appIsPaused(); } @Override protected void onDestroy() { flutterView.detachFromFlutterEngine(); super.onDestroy(); } }
def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 29 lintOptions { disable 'InvalidPackage' } defaultConfig { applicationId "io.flutter.examples.flutter_view" minSdkVersion 16 targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } } flutter { source '../..' } dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'com.google.android.material:material:1.0.0' }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <io.flutter.embedding.android.FlutterView android:id="@+id/flutter_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:background="@color/grey" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/button_tap" android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/button_tap" android:layout_weight="1" android:gravity="center" android:textSize="@dimen/font_size" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/android" android:layout_margin="@dimen/edge_margin" android:textSize="@dimen/platform_label_font_size" android:background="@color/grey" /> </LinearLayout> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|right" android:elevation="@dimen/fab_elevation_resting" app:pressedTranslationZ="@dimen/fab_elevation_pressed" android:layout_margin="@dimen/edge_margin" android:src="@drawable/ic_add_black_24dp" android:clickable="true" app:rippleColor="@color/grey" app:fabSize="normal" app:backgroundTint="@color/white" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> </LinearLayout>