基本介紹
flutter是google的跨平臺開發框架, 他和react native及weex框架的最大差別是flutter不使用原生控制元件而使用gdi按幀渲染, 個人理解非常類似windows時代的DirectUI。本文將介紹如何在一個已有的安卓專案中新增flutter, 使得部分新功能採用flutter
移植的基本思想是新建一個flutter功能 和安卓工程對比看看差異在哪裡, 並從flutter工程複製一些程式碼到安卓工程
操作過程 目錄結構 一個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
複製程式碼
然後,修改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點內容後,就可以在Android原生專案中執行Fluuter程式碼了。