appPackageName возвращает значение null, даже если AppObject не равен null

#android #kotlin #nullpointerexception #android-adapter #package-name

#Android #kotlin #исключение nullpointerexception #android-адаптер #package-name

Вопрос:

Я совершенно новый разработчик приложений, создающий приложение для запуска с использованием Kotlin. Я запускаю следующий код, чтобы запускать приложения из созданного мной ящика приложений:

 class AppAdapter(context:Context, appList:List<AppObject>):BaseAdapter() {
private val context:Context
private val appList:List<AppObject>
private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
init{
    this.context = context
    this.appList = appList
}

override fun getCount(): Int {
    return appList.size
}

override fun getItem(position:Int): Any {
    return appList[position]
}

override fun getItemId(position:Int):Long {
    return position.toLong()
}

override fun getView(position:Int, convertView:View?, parent:ViewGroup):View
{
    val v:View
    if (convertView == null)
    {
        v = inflater.inflate(R.layout.item_app, parent, false)
    }
    else
    {
        v = convertView
    }

    val myLayoutView = v.findViewById(R.id.layout) as LinearLayout
    val myImageView = v.findViewById(R.id.image) as ImageView
    val myLabelView =v.findViewById(R.id.label) as TextView

    val app = getItem(position) as AppObject
    myLabelView.text = app.appName
    myImageView.setImageDrawable(app.appImage)

    myLayoutView.setOnClickListener(object : View.OnClickListener {
        override fun onClick(v: View) {
            println(app)
            val applicationPackageName: String? = app.appPackageName
            if (applicationPackageName != null) {
                val launchAppIntent = context.packageManager.getLaunchIntentForPackage(app.appPackageName)
                if (launchAppIntent != null) {
                    context.startActivity(launchAppIntent)
                }
            }
        }
    })
    return v
}
  

}

И AppObject

 class AppObject(packageName:String?, name:CharSequence, image:Drawable) {
val appName:CharSequence
val appPackageName:String?
var appImage:Drawable
init{
    this.appName = name
    this.appPackageName = packageName
    this.appImage = image
}
  

}

Обращая особое внимание на

 println(app)
  

В моем классе AppAdapter у меня нет проблем с получением результатов, когда я нажимаю на макеты приложений в моем ящике с помощью этого оператора. Например, вот мои результаты запуска, когда я нажимаю на три разных приложения:

I/System.out: com.example.gotime_aparentalcontrolandproductivityapp.AppObject@84ad308 I/System.out: com.example.gotime_aparentalcontrolandproductivityapp.AppObject@4587aa1 I/System.out: com.example.gotime_aparentalcontrolandproductivityapp.AppObject@88f74c6

Но когда я меняю оператор печати, чтобы включить имя пакета:

 println(app.appPackageName)
  

Я получаю только:
I/System.out: null I/System.out: null I/System.out: null

Что я делаю не так?

У меня такое чувство, что это не вина, но я хотел бы отметить Emulator: emulator: INFO: QtLogger.cpp:68: Critical: Uncaught TypeError: Cannot read property 'update' of undefined , что время от времени я получаю сообщение об ошибке эмулятора. И я уже выполнил холодную перезагрузку своего AVD (Nexus 5X API 29)

Любая помощь или предложения приветствуются. Спасибо!

Комментарии:

1. Вопросы: 1. Что такое AppObject ? это созданный вами объект? 2. Вы уверены, что значение only appPackageName не равно null? Возможно, логика получения appPackageName вызывает проблему.

2. Привет, спасибо @Sylwek хорошая мысль. Вот AppObject: class AppObject(packageName:String?, name:CharSequence, image:Drawable) { val appName:CharSequence val appPackageName:String? var appImage:Drawable init{ this.appName = name this.appPackageName = packageName this.appImage = image } }

3. Глядя на это, кажется, что ваш packageName обнуляемый. и, возможно, есть какая-то проблема с приведением. Можете ли вы попробовать установить значение по умолчанию = «» также, возможно, рассмотрите возможность использования класса данных. data class AppObject(val packageName: String = "", val name: CharSequence, val image: Drawable) Таким образом, конструктор не требуется.

4. @Sylwek Хорошо, я пытаюсь, но не могу пройти мимо настройки изображения. Я понятия не имею, как инициализировать изображение, и ни один онлайн-ресурс не смог показать мне, как это сделать data class AppObject(val packageName:String, val name:CharSequence, val image:Drawable) { val appName:CharSequence = "" val appPackageName:String = "" val image:Drawable = ???? }

5. Ну, может быть довольно сложно установить значение по умолчанию для drawable, поскольку оно содержит ресурсы. Если вы ожидаете, что оно не будет null, вам не нужно устанавливать значение по умолчанию, а просто установить image при создании объекта. Класс данных в kotlin вообще не требует body, поэтому вы можете использовать его следующим образом. значение t = AppObject(«test»,»test1″,resources.getDrawable(R.drawable.id )). Если вы посмотрите на мой пример выше, вы увидите, что я установил значение по умолчанию в конструкторе.