Skip to content

Instantly share code, notes, and snippets.

@thedroiddiv
Last active October 7, 2022 17:34
Show Gist options
  • Save thedroiddiv/28a86034d60f55970823fbe83044525f to your computer and use it in GitHub Desktop.
Save thedroiddiv/28a86034d60f55970823fbe83044525f to your computer and use it in GitHub Desktop.
Divyansh Kushwaha's GSoC 2022 Report

GSoC logo

Divyansh Kushwaha's GSoC 2022 Report

Name Divyansh Kushwaha
Organization AnkiDroid
Proposal Divyansh's GSoC Proposal
Objective AsyncTask to Coroutines Migration Issue #7108

Hi I am Divyansh, and I've finally completed my Google Summer of Code 2022 project under the mentorship of organisation AnkiDroid

What is AnkiDroid?

AnkiDroid is an Android companion app for Anki, a flashcards application that helps people learn and memorize a diverse variety of topics.

AnkiDroid: Anki flashcards on Android. Your secret trick to achieve superhuman information retention.

First interaction with maintainers

My first interaction with a maintainer happened accidentally. I was working for a startup which used a fork of AnkiDroid as a base of their project. I had to remove the sync feature from existing fork and I mistakenly made a pull request to the main AnkiDroid repo 😆(kind of felt funny, but yeah this was it). So my first PR was an accidental one and was closed unmerged. David Allison was the first to comment on that and asked me to share a link to the project, so I joined discord server. And that was the begining of me starting contributing to AnkiDroid. There I saw a separate channel for GSoC, and since I was looking to apply for it I started asking questions on the server and found the community very welcoming and helpful. From there my journey to open source contributions began.

Initial Contributions

After joining the discord server, I came to know that there is something called good first issues which is for newcomers to get familiar and start their contributions. During that time, AnkiDroid was going through Java to Kotlin migrations. There were some changes that would reduce and simplify code using Koltin features, such changes were marked as KotlinCleanup. Before starting GSoC I started with these cleanup tasks. And eventually started working on migration of startActivityForResult to newer APIs. Done a few KotlinMigrations myself as well.

Objective

AnkiDroid was initially built on Java and used AsyncTask to handle asynchronous operations. Since AsyncTask is deprecated and AnkiDroid was already migrating to Kotlin, the asynchronous operations such as network calls, database access etc can be moved to Kotlin Coroutines. I already wanted to learn more about concurrency and parallelism concepts.

So, the Migration from AsyncTask to Coroutines was the objective of my GSoC project.

Application for GSoC

After choosing the GSoC topic and getting familiar with the codebase, it was time to prepare my proposal. For that I really needed to put together my strategies which I could use to do the migration. After going through these all, I did a sample migration just to show how the actual project might look like. I wrote the Application from the standard template that was provided by the organisation only. I asked for a review on my Application by maintainers and received a lot of them. It went through 3-4 rounds of review till I finally submitted my proposal.

Community Bonding Period

It is the initial time which Google gives to involve in the community activities that happened within an organisation. Since I already had been contributing and knew the community it went very well, even I started my coding in this period. I had a video call meet together with the other community members and my fellow GSoC students as well. I was a fun session and we shared our journey and experiences with the community so far.

Coding Period

First thing to do before starting the migration to Coroutines is to migrate required classes from Java to Kotlin because coroutines are a Kotlin feature. During the first week, I worked on migrating existing Java files which contain AsyncTask codes to Kotlin. I utilised my this time well by doing many Kotlin migrations. Thanks to the automated script that we have in AnkiDroid which made this process a lot easier. For migration to Kotlin we followed a specific set of rules to make sure nothing breaks and transition is smooth (like avoiding functional changes). A more detailed documentation is written by community members which you can find here.

For the coroutines, my initial planning was to create a base wrapper class similar to AsyncTask but instead of using underlying raw threads I would use suspend functions for the callbacks. I thought that migration should be done without changing the already existing architecture, like a patch on existing code but discussing with the mentors and other community members I came to a conclusion to follow a different approach. Most of the architecture was laid down to handle cancellations and memory leaks due to AsyncTask which we do not need to worry about when using Coroutines. Using right CoroutineScopes and bounding the coroutines to a LifecycleOwner handle these two very well, so we do not have to worry about checking if the UI is still alive or not.

Following a strategy, the doInBackground callback of AsyncTask would be replaced by a suspend function performing the same operation. And onPreExecute and onPostExecute callbacks would be called as it is before and after calling the suspend function. Using this concept, I started migrating firstly with the independent classes and later when I became much familiar with the codebase I started migrating the more core part of the codebase.

List of merged PRs in which I've done the migrations:

  1. Migrate PerformDowngradeTask to Coroutines #11651
  2. migrated AnkiStatsTaskHandler.createReviewSummaryStatistics() to suspend function #11667
  3. migrated LoadPronunciationActivity to Coroutines #11681
  4. migrated CollectionLoader to Coroutines #11816
  5. Migrated CollectionTask.AddNote to Coroutines #11952
  6. Migrated CollectionTask.UpdateNote to Coroutines #12199
  7. Migrated CollectionTask.UpdateMultipleNotes to Coroutines #12272
  8. Migrated LoadDeck to Coroutines #12328
  9. Coroutines migration PreloadNextCard #12362
  10. Coroutines migration CollectionTask.DeleteModel #12365
  11. Migrated LoadCollectionComplete to Coroutines #12361
  12. Coroutines migration CollectionTask.SaveCollection #12330
  13. migrated AnkiStatsTaskHandler.createStatisticsOverview() to suspend function #11628
  14. migrated AnkiStatsTaskHandler.createChart() to suspend function #11556
  15. Coroutines migration DeleteMedia #12373
  16. Coroutines migration CheckMedia #12375
  17. Coroutines migration CollectionTask.DeleteDeck #12391
  18. Coroutines migration ChangeSortField #12421
  19. Coroutines migration add field #12434
  20. Migrated CollectionTask. ConfReset to Kotlin Coroutines #12454
  21. Migrated CollectionTask.Flag to Coroutines #12462
  22. Migrated RepairCollection to Coroutines #12498
  23. Coroutines migration UpdateValuesFromDeck #12522
  24. Coroutines migration CollectionTask.MarkNoteMulti #12525
  25. Coroutines migration conf change #12534
  26. Coroutines migration save model #12535
  27. Migrated CountModels to Coroutines #12541
  28. Migrated ConfRemove to Coroutines #12546
  29. Migrated EmptyCram to Coroutines #12551
  30. Migrated CheckCardSelection to Coroutines #12556
  31. Migrated CollectionTask.Reset to Coroutines #12557
  32. Coroutines migration RenderBrowserQA #12571
  33. Coroutines migration DeleteNoteMulti #12577
  34. Coroutines migration RebuildCram #12584
  35. Coroutines migration SuspendCardMulti #12585
  36. Migrated CollectionTask.Reorder to Coroutines #12591
  37. Coroutines migration ConfSetSubdecks #12592

After the migration, I realised that I have completely deviated from my initial plans but for good. Migrating with the newer approach made the codes much cleaner and easy to follow.

Final Results

Since my changes do not include UI changes, I cannot show it but by the end of GSoC I have migrated most parts of the AnkiDroid to Coroutines. Although I couldn't complete everything within the given timeline, but yeah almost 80-85 percent of the migration has been done. I be also keep contributing to the AnkiDroid after GSoC and will put my efforts to improve the codebase. I would like to thank Shridhar, Arthur, Mike, Luksbit, David and other folks around the community. You guys are awesome and I've had a very good time together with you spending my summer discussing and programming.

Learning Outcomes

Before working on GSoC I did not have much experience with Git-GitHub workflow, PRs, Code reviews, coding discussion, planning, having conversations with community members, etc. These are the most valuable things I would say I learned from my GSoC period. Also working on the project I learned Kotlin Coroutines in great depth along with the concepts of AsyncTask, how Android used to be before Kotlin. I would say GSoC had a very large impact on my skills.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment