Skip to content

Support for debugging add-to-app modules in Android Studio #4097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 14, 2019

Conversation

stevemessick
Copy link
Member

@stevemessick stevemessick commented Nov 12, 2019

Address all P1 items in #4064.
cc: @xster

Create and debug a Flutter module in an Android app

Create an Android app

Start Android Studio and use the File > New > New Project menu to fire
up the new project wizard. Choose the template that includes a Basic
Activity. One the next page, use Kotlin and minimum API level 16.
Let the system stabilize (Gradle sync).

Close the editor for content_main.xml. Switch the Project view to
the Project Files mode. Collapse the Gradle window if it is open.

Create a Flutter module

Use the File > New > New Module menu to start the new module wizard.
Choose the Flutter Module template. Fill out the wizard pages and
click Finish, then wait a bit. Android Studio needs to do two
successive Gradle sync's. The first one generates an error message,
which is corrected by the second one. Ignore the error. Let the
system stabilize again.

Link the Flutter module to the Android app

Go to the editor for MainActivity.kt. Change the onCreate method:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)
        val engine = FlutterEngine(this.applicationContext)
        engine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
        fab.setOnClickListener { view ->
            FlutterEngineCache.getInstance().put("1", engine)
            startActivity(FlutterActivity.withCachedEngine("1").build(this))
        }
    }

You need to add some imports. Click on each red name then type
alt-return. Accept the suggestion. "FlutterActivity" has two choices;
use the one from io.flutter.embedGradle.

Open an editor on the AndroidManifest.xml. Add this line to the
tag:

        <activity android:name="io.flutter.embedding.android.FlutterActivity" />

Debug the app

The run config should show the Flutter run config, which makes the Flutter Attach
button active. Click the Flutter Attach button, or use the menu item Run > Flutter
Attach. (Note: with the kotlin code above you need to start the attach process
before starting the Android app.)

Change the run config to "app" for the Android app. Click the Debug button.
Wait for the app to launch.

When the app is visible, click the mail icon at bottom right. The Flutter
screen should become visible. At this point you can set breakpoints and
do hot reload as for a stand-alone Flutter app.

@xster
Copy link
Member

xster commented Nov 12, 2019

Thanks @stevemessick! This is super awesome.

2 questions on the readme.

@matthew-carroll, I think we don't need System.loadLibrary("flutter"); FlutterMain.startInitialization(this.applicationContext); FlutterMain.ensureInitializationComplete(this, null) anymore. If you're on master of the framework (what we'll most likely ship by December), it should work with just the remaining lines. Were you getting an error @stevemessick?

@blasten, it seems like flutter attach here "just works" on Android. Is the IDE doing something special to catch the debug-uri for the observatory?

@matthew-carroll
Copy link

@xster that's correct. I don't think we should need any loading/initialization code from the app developer anymore.

@stevemessick
Copy link
Member Author

@xster TBH I just wrote the test code based on a test app from the Flutter repo. The simplification works so I changed the testing doc. I'll edit the comment, too.

And yes, the IDE does quite a bit to handle attach. It's been over a year since I looked at that code and am fuzzy on details. It sets up a debug listener that runs when the VM service protocol says a debug launch is happening.

@xster
Copy link
Member

xster commented Nov 13, 2019

Understood

wrt the service protocol thing @devoncarew, @zanderso, @blasten when we're cleaning up the attach logic at some point later on in Q4, it would be nice to deduplicate these IDE and/or tool logic.

@xster
Copy link
Member

xster commented Nov 13, 2019

Can't review the plugin code but the usage instructions LGTM!

Thanks Steve

@devoncarew
Copy link
Member

fixes #4069


// Setup a default run configuration for 'main.dart' (if it's not there already and the file exists).
PubRoot pubRoot = PubRoot.forDirectory(moduleRoot);
assert(pubRoot != null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How similar is this code path to the one in FlutterBuildActionGroup.build()? I ask because we (very infrequently) see an NPE from there when the pubRoot is null. #4065

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's possible here as well, we'd want to handle null instead of asserting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any similarity. Looking at the caller of FlutterBuildActionGroup.build() I see it does PubRoot.forEventWithRefresh(event). My guess is the null arises because the event changes status before that expression runs, and the Project cannot be retrieved from the event. All I have is anecdotal evidence for this, but I think JetBrains is tightening controls on how much can be done on the EDT, probably to improve responsiveness. We should look at callers of forEventWithRefresh and rewrite them to ensure the Project is fetched early.

@xster
Copy link
Member

xster commented Nov 13, 2019

Is there a way I can try this plugin locally?

@stevemessick
Copy link
Member Author

@xster I'll contact you via email.

@stevemessick stevemessick merged commit 584b720 into master Nov 14, 2019
@stevemessick stevemessick deleted the debug-modules branch November 14, 2019 18:13
alexander-doroshko pushed a commit to alexander-doroshko/flutter-intellij that referenced this pull request Jan 24, 2020
)

* Support for debugging add-to-app modules in Android Studio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants