Anko: Alertdialog can't find referenced class

Created on 6 Jun 2017  路  2Comments  路  Source: Kotlin/anko

If you are showing a alert dialog within a forEach loop, I get the following warning when compiling on the command line.

Warning: com.testapp.MainActivity$showDialog$1$1$2: can't find referenced class com.testapp.MainActivity$showDialog$1$1
Warning: com.testapp.MainActivity$showDialog$1$1$2: can't find referenced class com.testapp.MainActivity$showDialog$1$1

I used the following code to reproduce it:

    val list = ArrayList<String>();
    list.forEach {
        alert {
            message = "This message"
            positiveButton("Action", {
                doSomething()
            })
            negativeButton("Cancel", {})
        }.show()
    }

And this is caused by the empty lambda in the negativeButton, removing that solves the gradle warning.

This only happens when proguard is enabled (with the default rules file)
Kotlin version: 1.1.2-4
anko commons: 0.10.0

Most helpful comment

I have a similar issue for a different piece of code:

class DepotActivity {
    var allCategories: SparseArray<Category>?
    ...
    fun showMenuFragment(fragmentTag: String, fragmentCreator: () -> DialogFragment) {...}
    ...
    private fun showCategoryChoice() {
        allCategories?.let { allCats ->
            showMenuFragment("categories") {
                val count = allCats.size()
                val categories = ArrayList<Category>(count)
                (0 until count).mapTo(categories) { allCats.valueAt(it) }
                categories.sortBy { it.name.toLowerCase(Locale.getDefault()) }
                CategoryViewFragment.newInstance(categories)
            }
        }
    }
}

It will raise a warning like: ...DepotActivity$showHideCategoryChoice$1$1$2: can't find referenced class ...DepotActivity$showHideCategoryChoice$1$1
When look at the generated code, it will create a class like ...DepotActivity$showHideCategoryChoice$$inlined$let$lambda$1 extends Lambda implements Function0
and the function showCategoryChoice is like:

private final void showCategoryChoice() {
  SparseArray var10000 = this.allCategories;
  if(this.allCategories != null) {
     SparseArray var1 = var10000;
     this.showMenuFragment("categories", (Function0)(new DepotActivity$showCategoryChoice$$inlined$let$lambda$1(var1, this)));
  }
}

Now if I change a little bit the function into:

private fun showCategoryChoice() {
    val allCats = allCategories
    if (allCats != null) {
        showHideMenuFragment("categories") {
        ...
        }
    }
}

Then there will be no Proguard warnings and if we look at the generated code, everything is inlined as expected, no extra class generated.

That being said, I don't thing this is related to anko but rather a bug in kotlin compiler

All 2 comments

I have the same issue too. Removing anko's alert {...} fixes this issue, and I can't seem to find which proguard rule helps in this situation

I have a similar issue for a different piece of code:

class DepotActivity {
    var allCategories: SparseArray<Category>?
    ...
    fun showMenuFragment(fragmentTag: String, fragmentCreator: () -> DialogFragment) {...}
    ...
    private fun showCategoryChoice() {
        allCategories?.let { allCats ->
            showMenuFragment("categories") {
                val count = allCats.size()
                val categories = ArrayList<Category>(count)
                (0 until count).mapTo(categories) { allCats.valueAt(it) }
                categories.sortBy { it.name.toLowerCase(Locale.getDefault()) }
                CategoryViewFragment.newInstance(categories)
            }
        }
    }
}

It will raise a warning like: ...DepotActivity$showHideCategoryChoice$1$1$2: can't find referenced class ...DepotActivity$showHideCategoryChoice$1$1
When look at the generated code, it will create a class like ...DepotActivity$showHideCategoryChoice$$inlined$let$lambda$1 extends Lambda implements Function0
and the function showCategoryChoice is like:

private final void showCategoryChoice() {
  SparseArray var10000 = this.allCategories;
  if(this.allCategories != null) {
     SparseArray var1 = var10000;
     this.showMenuFragment("categories", (Function0)(new DepotActivity$showCategoryChoice$$inlined$let$lambda$1(var1, this)));
  }
}

Now if I change a little bit the function into:

private fun showCategoryChoice() {
    val allCats = allCategories
    if (allCats != null) {
        showHideMenuFragment("categories") {
        ...
        }
    }
}

Then there will be no Proguard warnings and if we look at the generated code, everything is inlined as expected, no extra class generated.

That being said, I don't thing this is related to anko but rather a bug in kotlin compiler

Was this page helpful?
0 / 5 - 0 ratings

Related issues

HarryTylenol picture HarryTylenol  路  3Comments

red1004g picture red1004g  路  5Comments

bapspatil picture bapspatil  路  4Comments

jeantuffier picture jeantuffier  路  5Comments

SuleymanovTat picture SuleymanovTat  路  4Comments