Crazy Android Studio использование памяти - PullRequest
0 голосов
/ 12 марта 2020

Это мое последнее средство - очень надеюсь, что у кого-то есть подсказка.

Я создал следующий кастом OnboardingGuideView. Когда я добавляю его в отображаемый макет, компьютер (Ma c или Windows) начинает кричать, память достигает вершины и Android Studio (версия 3.6.1) зависает , как будто есть некоторый рекурсивный элемент, который где-то блокирует IDE.

Я пробовал комментировать фрагменты кода один за другим, пока все не было прокомментировано. Тем не менее, когда я запускаю Android Studio (не делая ничего другого), запускается "вечеринка", и через минуту AS замораживается.

Если компонент <dk.tdc.selfapp.ui.common.widgets.onboardingguide.OnboardingGuideView прокомментирован, все в порядке.

Мое королевство для решения!

Вид добавлен в макет:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/RowStyle"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <dk.tdc.selfapp.ui.common.widgets.onboardingguide.OnboardingGuideView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:background="@color/errorRed10Color"
        app:descriptionPrefix="tdc_esim_finalize_guide_description"
        app:imagePrefix="esim_finalize_guide_image"
        app:titlePrefix="tdc_esim_finalize_guide_title" />

...

Вид:

import android.content.Context
import android.text.Html
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import dk.firm.oldapp.R
import kotlinx.android.synthetic.main.view_onboarding_guide.view.*

class OnboardingGuideView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : FrameLayout(context, attrs, defStyleAttr) {

    private var itemCount = 0
    private var titlePrefix = ""
    private var descriptionPrefix = ""
    private var imagePrefix = ""

    init {
        LayoutInflater.from(context)
                .inflate(R.layout.view_onboarding_guide, this, true)
        setAttributes(attrs)
    }

    private fun setAttributes(attrs: AttributeSet?) {
        attrs?.let { a ->
            val typedArray = context.obtainStyledAttributes(a,
                    R.styleable.OnboardingGuideView, 0, 0)
            titlePrefix = typedArray.getString(R.styleable.OnboardingGuideView_titlePrefix).toString()
            descriptionPrefix = typedArray.getString(R.styleable.OnboardingGuideView_descriptionPrefix).toString()
            imagePrefix = typedArray.getString(R.styleable.OnboardingGuideView_imagePrefix).toString()

            typedArray.recycle()
        }

        setup()
    }

    private fun setup() {
        itemCount = countResources(titlePrefix, "string")
        val adapter = OnboardingGuideAdapter(context, itemCount, titlePrefix, descriptionPrefix, imagePrefix)
        itemPager.adapter = adapter

        addDotsIndicator()
    }

    private fun countResources(prefix: String, type: String): Int {
        var id: Long = -1
        var count = -1

        while (id != 0L) {
            count++
            id = context.resources.getIdentifier(String.format("%s_%s", prefix, (count + 1)),
                    type, context.packageName).toLong()
        }

        return count
    }

    private fun addDotsIndicator() {
        indicatorView.removeAllViews()

        for (i in 0 until itemCount) {
            val dot = TextView(context)
            dot.text = Html.fromHtml("&#8226;")
            dot.textSize = 35F
            dot.setTextColor(resources.getColor(R.color.appColorBlueLight))

            indicatorView.addView(dot)
        }
    }
}

Просмотр макета - view_onboarding_guide:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/itemPager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:id="@+id/indicatorView"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/status_text_color_red"
        android:orientation="horizontal" />
</LinearLayout>

Адаптер:

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.viewpager.widget.PagerAdapter
import dk.firm.oldapp.R
import dk.firm.selfapp.util.Utils

class OnboardingGuideAdapter(
        val context: Context,
        private val itemCount: Int,
        private val titlePrefix: String,
        private val descriptionPrefix: String,
        private val imagePrefix: String) : PagerAdapter() {

    override fun getCount(): Int {
        return itemCount
    }

    override fun isViewFromObject(view: View, o: Any): Boolean {
        return view == o as LinearLayout
    }

    override fun instantiateItem(container: ViewGroup, position: Int): Any {
        val view = LayoutInflater.from(context).inflate(R.layout.view_onboarding_guide_item, container, false)
        val ordinal = position + 1

        // Instantiate views
        val titleView = view.findViewById<TextView>(R.id.onBoardingItemTitle)
        val descriptionView = view.findViewById<TextView>(R.id.onBoardingItemDescription)
        val imageView = view.findViewById<ImageView>(R.id.onBoardingItemImage)

        // Create resource names
        val title = String.format("%s_%s", titlePrefix, ordinal)
        val description = String.format("%s_%s", descriptionPrefix, ordinal)
        val image = String.format("%s_%s", imagePrefix, ordinal)

        // Populate views
        titleView.text = Utils.getStringFromResId(context.resources.getIdentifier(title, "string", context.packageName))
        descriptionView.text = Utils.getStringFromResId(context.resources.getIdentifier(description, "string", context.packageName))
        imageView.setImageResource(context.resources.getIdentifier(image, "drawable", context.packageName))

        container.addView(view)

        return view
    }

    override fun destroyItem(container: ViewGroup, position: Int, o: Any) {
        container.removeView(o as LinearLayout)
    }
}

Элемент макета - view_onboarding_guide_item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/onBoardingItemTitle"
        style="@style/TextAppearance.Subtitle1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/onBoardingItemDescription"
        style="@style/TextAppearance.Body1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/onBoardingItemImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Ответы [ 2 ]

0 голосов
/ 17 марта 2020

После того, как эта проблема осталась за пределами Windows и воспроизведена на Ма c и Linux, мой коллега воспользовался возможностью, чтобы покопаться в ней, и он придумал это:

init {
    LayoutInflater.from(context).inflate(R.layout.view_onboarding_guide, this, true)
    if (!isInEditMode) // <- this :-(
        setAttributes(attrs)
}

.. которая решила проблему. Это выглядит для меня совершенно безумно и сильно воняет из-за ошибки в AS.

Я создал бесчисленное множество пользовательских представлений и никогда не сталкивался с такой проблемой, которая требовала использования isInEditMode в представлении.

Я, конечно, буду помнить об этом в будущем, но если кто-нибудь может объяснить, почему это помогает и почему это не ошибка, тогда я буду признателен за это.

0 голосов
/ 12 марта 2020

Android Студия, как известно, перегружает память, черта, унаследованная от IDE IntelliJ, из которой она получена. Вы можете увидеть, сколько памяти AS использует и доступно для нее в правом нижнем углу экрана:

Memory usage indicator and surrounding icons

(Это может не отображается постоянно, это настройка, которую можно включить в настройках приложения, если она не отображается)

Во-первых, вы можете сказать AS, чтобы очистить память, которую он не использует, нажав на эту readout!

Во-вторых, замораживание AS обычно указывает на то, что ему нужно немного больше, чем выделено. К счастью, вы можете увеличить лимит самостоятельно. Как показывает ProAndroidDev , вы можете редактировать параметры виртуальной машины для студии:

Go до Help > Edit Custom VM Options и редактировать следующие два атрибута:

Xmx: По умолчанию это 1280m, PAD рекомендует изменить это значение на 4096m

XX:MaxPermSize: По умолчанию это 350m, PAD рекомендует изменить это значение на 1024m

. и другие) значения: Ознакомьтесь с этой статьей о пользовательских параметрах виртуальной машины и ускорении Android Studio .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...