mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Merge pull request #2673 from jason-simmons/gradle_example
Example that builds a Flutter Android app using Gradle
This commit is contained in:
commit
2fdcb59fec
16
examples/hello_android/README.md
Normal file
16
examples/hello_android/README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Example of building a Flutter app for Android using Gradle
|
||||||
|
|
||||||
|
This project demonstrates how to embed Flutter within an Android application
|
||||||
|
and build the Android and Flutter components with Gradle.
|
||||||
|
|
||||||
|
To build this project:
|
||||||
|
|
||||||
|
* Create a `local.properties` file with these entries:
|
||||||
|
* `sdk.dir=[path to the Android SDK]`
|
||||||
|
* `flutter.sdk=[path to the Flutter SDK]`
|
||||||
|
* `flutter.jar=[path to the flutter.jar file in your build of the Flutter engine]`
|
||||||
|
|
||||||
|
Then run:
|
||||||
|
|
||||||
|
* `gradle wrapper`
|
||||||
|
* `./gradlew build`
|
15
examples/hello_android/app/build.gradle
Normal file
15
examples/hello_android/app/build.gradle
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'flutter'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 22
|
||||||
|
buildToolsVersion '22.0.1'
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
disable 'InvalidPackage'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flutter {
|
||||||
|
source 'src/flutter'
|
||||||
|
}
|
7
examples/hello_android/app/src/flutter/lib/main.dart
Normal file
7
examples/hello_android/app/src/flutter/lib/main.dart
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
void main() => runApp(new Center(child: new Text('Hello from Flutter!')));
|
4
examples/hello_android/app/src/flutter/pubspec.yaml
Normal file
4
examples/hello_android/app/src/flutter/pubspec.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
name: gradle
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
path: ../../../../../packages/flutter
|
25
examples/hello_android/app/src/main/AndroidManifest.xml
Normal file
25
examples/hello_android/app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.example.flutter"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0.0" >
|
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
|
<application android:name="org.domokit.sky.shell.SkyApplication" android:label="@string/app_name" >
|
||||||
|
<activity
|
||||||
|
android:name=".FlutterActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:theme="@android:style/Theme.Black.NoTitleBar"
|
||||||
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package com.example.flutter;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.chromium.base.PathUtils;
|
||||||
|
import org.domokit.sky.shell.SkyApplication;
|
||||||
|
import org.domokit.sky.shell.SkyMain;
|
||||||
|
import org.domokit.sky.shell.PlatformViewAndroid;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class FlutterActivity extends Activity {
|
||||||
|
private PlatformViewAndroid flutterView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
SkyMain.ensureInitialized(getApplicationContext(), null);
|
||||||
|
setContentView(R.layout.flutter_layout);
|
||||||
|
|
||||||
|
flutterView = (PlatformViewAndroid) findViewById(R.id.flutter_view);
|
||||||
|
File appBundle = new File(PathUtils.getDataDirectory(this), SkyApplication.APP_BUNDLE);
|
||||||
|
flutterView.runFromBundle(appBundle.getPath(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
if (flutterView != null) {
|
||||||
|
flutterView.destroy();
|
||||||
|
}
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/title"
|
||||||
|
/>
|
||||||
|
<org.domokit.sky.shell.PlatformViewAndroid
|
||||||
|
android:id="@+id/flutter_view"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Flutter App</string>
|
||||||
|
<string name="title">Flutter Application</string>
|
||||||
|
</resources>
|
17
examples/hello_android/build.gradle
Normal file
17
examples/hello_android/build.gradle
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.5.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
||||||
|
|
||||||
|
task wrapper(type: Wrapper) {
|
||||||
|
gradleVersion = '2.8'
|
||||||
|
}
|
7
examples/hello_android/buildSrc/build.gradle
Normal file
7
examples/hello_android/buildSrc/build.gradle
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile "com.android.tools.build:gradle:1.5.0"
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package org.domokit.sky.gradle
|
||||||
|
|
||||||
|
import com.android.builder.model.AndroidProject
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.GradleException
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Task
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.tasks.Copy
|
||||||
|
import org.gradle.api.tasks.InputDirectory
|
||||||
|
import org.gradle.api.tasks.OutputDirectory
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
|
||||||
|
class FlutterPlugin implements Plugin<Project> {
|
||||||
|
private File sdkDir
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void apply(Project project) {
|
||||||
|
Properties properties = new Properties()
|
||||||
|
properties.load(project.rootProject.file("local.properties").newDataInputStream())
|
||||||
|
|
||||||
|
String enginePath = properties.getProperty("flutter.jar")
|
||||||
|
if (enginePath == null) {
|
||||||
|
throw new GradleException("flutter.jar must be defined in local.properties")
|
||||||
|
}
|
||||||
|
FileCollection flutterEngine = project.files(enginePath)
|
||||||
|
if (!flutterEngine.singleFile.isFile()) {
|
||||||
|
throw new GradleException("flutter.jar must point to a Flutter engine JAR")
|
||||||
|
}
|
||||||
|
|
||||||
|
String sdkPath = properties.getProperty("flutter.sdk")
|
||||||
|
if (sdkPath == null) {
|
||||||
|
throw new GradleException("flutter.sdk must be defined in local.properties")
|
||||||
|
}
|
||||||
|
sdkDir = project.file(sdkPath)
|
||||||
|
if (!sdkDir.isDirectory()) {
|
||||||
|
throw new GradleException("flutter.sdk must point to the Flutter SDK directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
project.extensions.create("flutter", FlutterExtension)
|
||||||
|
project.dependencies.add("compile", flutterEngine)
|
||||||
|
project.afterEvaluate this.&addFlutterTask
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFlutterTask(Project project) {
|
||||||
|
if (project.flutter.source == null) {
|
||||||
|
throw new GradleException("Must provide Flutter source directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
FlutterTask flutterTask = project.tasks.create("flutterBuild", FlutterTask) {
|
||||||
|
sdkDir this.sdkDir
|
||||||
|
sourceDir project.file(project.flutter.source)
|
||||||
|
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter")
|
||||||
|
}
|
||||||
|
|
||||||
|
project.android.applicationVariants.all { variant ->
|
||||||
|
Task copyFlxTask = project.tasks.create(name: "copyFlx${variant.name.capitalize()}", type: Copy) {
|
||||||
|
dependsOn flutterTask
|
||||||
|
dependsOn variant.mergeAssets
|
||||||
|
from flutterTask.flxPath
|
||||||
|
into variant.mergeAssets.outputDir
|
||||||
|
}
|
||||||
|
variant.outputs[0].processResources.dependsOn(copyFlxTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FlutterExtension {
|
||||||
|
String source
|
||||||
|
}
|
||||||
|
|
||||||
|
class FlutterTask extends DefaultTask {
|
||||||
|
File sdkDir
|
||||||
|
|
||||||
|
@InputDirectory
|
||||||
|
File sourceDir
|
||||||
|
|
||||||
|
@OutputDirectory
|
||||||
|
File intermediateDir
|
||||||
|
|
||||||
|
String getFlxPath() {
|
||||||
|
return "${intermediateDir}/app.flx"
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
void build() {
|
||||||
|
if (!sourceDir.isDirectory()) {
|
||||||
|
throw new GradleException("Invalid Flutter source directory: ${sourceDir}")
|
||||||
|
}
|
||||||
|
|
||||||
|
intermediateDir.mkdirs()
|
||||||
|
project.exec {
|
||||||
|
executable "${sdkDir}/bin/flutter"
|
||||||
|
workingDir sourceDir
|
||||||
|
args "build"
|
||||||
|
args "-o", flxPath
|
||||||
|
args "--snapshot", "${intermediateDir}/snapshot_blob.bin"
|
||||||
|
args "--depfile", "${intermediateDir}/snapshot_blob.bin.d"
|
||||||
|
args "--working-dir", "${intermediateDir}/flx"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
implementation-class=org.domokit.sky.gradle.FlutterPlugin
|
1
examples/hello_android/settings.gradle
Normal file
1
examples/hello_android/settings.gradle
Normal file
@ -0,0 +1 @@
|
|||||||
|
include ':app'
|
Loading…
Reference in New Issue
Block a user