기존 Android 앱에 Flutter UI를 추가하는 방법을 알아 내려고 며칠을 보냈습니다. 가장 큰 문제는 MethodChannel이 MainActivity에서 호출 된 FlutterActivity와 작동하도록하는 것이 었습니다. 나는 이것이 여기에서 묻는 질문과 약간 다르다는 것을 알고 있지만 'Android FlutterActivity MethodChannel'을 검색했을 때이 게시물이 반환되었습니다. 이 작업을 수행하는 방법에 대한 많은 리소스를 사용한 후에 마침내 여기에서 솔루션을 찾았습니다.
https://github.com/flutter/samples/tree/master/add_to_app/android_using_plugin/app/src/main/java/dev/flutter/ 예제 / androidusingplugin
처음에는 Android Studio에서 기존 앱이 열린 상태에서 File, New, New Module, Flutter Module을 탭했습니다. 오류가 발생하여 수동 단계를 수행해야했습니다.
내 목표는 MainActivity-onCreate에서 FlutterActivity (flutter_module에서 main.dart를 엽니 다)를 시작한 다음 MethodChannel을 사용하여 제한된 플랫폼 호출로 가능한 한 많은 네이티브 Flutter 코드를 활용하여 Flutter '스크린'을 개발하는 것입니다. 대체 Flutter 코드를 개발할 때 기존 Android 코드를 계속 주석 처리합니다.
마지막으로 나를 위해 일한 것은 다음과 같습니다.
../App_Project/Android/Existing_Android_App/settings.gradle
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir.parentFile, '../flutter_module/.android/include_flutter.groovy'))
include ':flutter_module’
project(':flutter_module’).projectDir = new File('../../flutter_module’)
rootProject.name=‘existing_android_app’
../App_Project/Android/Existing_Android_App/app/build.gradle
dependencies {
…
implementation project(':flutter')
}
../App_Project/Android/Existing_Android_App/app/src/main/AndroidManifest.xml
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" />
../App_Project/Android/Existing_Android_App/app/src/main/java/com/existing_android_app/MainActivity.java
package com.existing_android_app;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class MainActivity extends AppCompatActivity {
final String ENGINE_ID = "1";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FlutterEngine flutterEngine = new FlutterEngine(this);
flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
FlutterEngineCache.getInstance().put(ENGINE_ID, flutterEngine);
MethodChannel channel = new MethodChannel(flutterEngine.getDartExecutor(), "com.existing_android_app/myMethodChannel");
channel.setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
String url = call.argument("url");
if (call.method.equals("openBrowser")) {
openBrowser(url);
}
else {
result.notImplemented();
}
}
});
startActivity(FlutterActivity.withCachedEngine(ENGINE_ID).build(this));
}
void openBrowser(String url) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
this.startActivity(intent);
}
}
../App_Project/flutter_module/lib/home_page.dart
class AppHomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<AppHomePage> {
static const platform = const MethodChannel(‘com.existing_android_app/myMethodChannel’);
Future<void> _openBrowser() async {
try {
final int result = await platform.invokeMethod('openBrowser', <String, String> { 'url': "http://bing.com” });
}
catch (e) {
print('***** _openBrowser error: ' + e.toString());
}
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: CustomAppBar(),
body: Column(
children: <Widget>[
RaisedButton(
label: Text('Search',
style: TextStyle(fontSize: 18.0),
),
onPressed: () { _openBrowser(); },
) // RaisedButton.icon
], // Widget
) // Column
) // Scaffold
); // SafeArea
}