在已有android studio工程中添加flutter

基本介绍

flutter是google的跨平台开发框架, 他和react native及weex框架的最大差别是flutter不使用原生控件而使用gdi按帧渲染, 个人理解非常类似windows时代的DirectUI

老工程集成flutter有两大方法:

  1. 把老工程完全改成flutter,这种方法能实现dart代码的动态加载,但改动很大, 因为flutter引擎内部写死了android-studio里的一些路径,如果AndroidManifest.xml的路径,改造可以做,但不一定有很好的兼容性 本文就介绍此种方法
  2. 制作一个纯的flutter工程A,fluuter的开发调试都在这个工程进行,当需要发布到老工程B时,把A工程flutter编译后的平台相关的中间文件复制到B工程,B工程没有dart的调试功能,类似与基础了一个第三方的功能模块, 参考另一篇blog: https://blog.csdn.net/langouster/article/details/81566668

操作过程

目录结构

一个android studio工程的目录结构是这样的
project
├─local.properties
├─build.gradle
├─settings.gradle
├─app
│ ├─build
│ ├─libs
│ └─src
└─gradle
└─wrapper

而flutter的目录结构是
flutter
├─android 对应安卓工程的project目录
├─build
├─ios
├─lib
└─pubspec.yaml

1, 所以第一步, 把project目录名改成android

工程修改

2.复制pubspec.yaml和lib文件到跟android并列
3.修改AndroidManifest.xml文件

    <application
        android:name="io.flutter.app.FlutterApplication"  加入这行
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            intent-filter>
        activity>
    application>

如果这边修改没成功运行时会报错如下

E/FlutterMain(13694): Flutter initialization failed.
E/FlutterMain(13694): java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.view.ResourceExtractor.waitForCompletion()' on a null object reference

4.修改settings.gradle

include ':app'

def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()

def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
    pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}

plugins.each { name, path ->
    def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
    include ":$name"
    project(":$name").projectDir = pluginDirectory
}

如果这步修改失败会提示GeneratedPluginRegistrant文件编译出错:
错误: 程序包io.flutter.plugins.pathprovider不存在
错误: 程序包io.flutter.plugins.sharedpreferences不存在

5.修改project的build.gradle,加入这一段

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

6.修改app的的build.gradle,加入这一段

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.")
}

apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"


android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "flutter_app2.yourcompany.com.myapplication"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

这个别忘了
flutter {
    source '../..'
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

7.修改local.properties加入fluttersdk的路径

ndk.dir=E\:\\software\\android-sdk-windows\\ndk-bundle
sdk.dir=E\:\\software\\android-sdk-windows
flutter.sdk=D:\\flutter
flutter.buildMode=debug
  1. 修改MainActivity.java

import android.os.Bundle;

import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class MainActivity extends FlutterActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);
    }
}

修改这8点内容后,编译运行看看,顺利的话就可以正常运行了

但是你会发现没有hot read热更新代码了, 别急, 先关闭工程
然后用android studio打开第一步中android文件夹的上层目录, 也就是pubspec.yaml所在的目录, android stdio发现存在文件pubspec.yaml,自动识别为一个flutter工程了, 就有热更新了

官方关于这块的文档见:https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps

你可能感兴趣的:(在已有android studio工程中添加flutter)