java.lang.RuntimeException: 尝试在活动之间切换时无法实例化 activity 错误

java.lang.RuntimeException: Unable to instantiate activity error when trying to switch between activities

我是新手,我正在尝试使用按钮将数据添加到共享首选项并将其显示在片段的列表视图中(它是主要活动)。当我点击浮动按钮时,出现错误:

{java.lang.RuntimeException: 无法实例化 activity ComponentInfo{com.example.calculator3dprinting/com.example.calculator3dprinting.PrinterAddActivity}: java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'android.content.Context android.content.Context.getApplicationContext()'}

这是片段和activity我想切换到

import android.content.Context.MODE_PRIVATE
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.ListView
import androidx.fragment.app.Fragment
import com.google.android.material.floatingactionbutton.FloatingActionButton


class PrinterFragment: Fragment() {
    private val TAG = "PrinterFragment"
    private lateinit var pMap: PrinterManager
    private lateinit var mListView: ListView
    private lateinit var sharedPreferences: SharedPreferences
    //private val db = DatabaseManager()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.printer_fragment, container, false)
        mListView = view.findViewById(R.id.ListView)

        val newPrinter: FloatingActionButton = view.findViewById(R.id.addPrinter)
        newPrinter.setOnClickListener {
            val intent = Intent(this.context, PrinterAddActivity::class.java)
            startActivity(intent)
        }

        //AsyncTask.execute() {
        populateListView(mListView, view)
        //}
        return view
    }

    private fun populateListView(mListView: ListView, view: View) {
        /*
        db.context = view.context
        db.initialize()

        val data = db.getPrinterNames()

        val adapter = ArrayAdapter(
            view.context, android.R.layout.simple_list_item_1, data
        )
        mListView.adapter = adapter

        mListView.onItemClickListener =
            OnItemClickListener { adapterView, _, i, _ ->
                val name = adapterView.getItemAtPosition(i).toString()
                Log.d(TAG, "onItemClick: You Clicked on $name")

                val itemId = db.getPrinterIdByName(name) //get the id associated with that name

                Log.d(TAG, "onItemClick: The ID is: $itemId")
                val editScreenIntent =
                    Intent(view.context, PrinterEditActivity::class.java)
                editScreenIntent.putExtra("id", itemId)
                startActivity(editScreenIntent)

            }
    }
    */
        sharedPreferences = requireContext().getSharedPreferences("Printers", MODE_PRIVATE)
        pMap = PrinterManager(sharedPreferences.all as MutableMap<Int, PrinterManager.Printers>)

        val pList = pMap.hashPrinter.values.toList()
        val adapter = ArrayAdapter(view.context, android.R.layout.simple_list_item_1, pList)
        mListView.adapter = adapter

        mListView.onItemClickListener =
            AdapterView.OnItemClickListener { adapterView, _, i, _ ->
                val name = adapterView.getItemAtPosition(i).toString()
                Log.d(TAG, "onItemClick: You Clicked on $name")

                val itemId = pMap.getIdByName(name) //get the id associated with that name

                Log.d(TAG, "onItemClick: The ID is: $itemId")
                val editScreenIntent =
                    Intent(view.context, PrinterEditActivity::class.java)
                editScreenIntent.putExtra("id", itemId)
                startActivity(editScreenIntent)
            }
    }
}
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

class PrinterAddActivity: AppCompatActivity() {
    //private val db = DatabaseManager()
    private lateinit var pMap: PrinterManager
    private val sharedPreferences: SharedPreferences
            = applicationContext.getSharedPreferences("Printers", MODE_PRIVATE)
    private val editor = sharedPreferences.edit()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_printer_add)

        val savePrinter: Button = findViewById(R.id.save_printerBtn)
        val backButton: Button = findViewById(R.id.back_printer)

        val editName: EditText = findViewById(R.id.pAdd_name)
        val editDiam: EditText = findViewById(R.id.materialAdd_diameter)
        val editPrice: EditText = findViewById(R.id.pAdd_price)
        val editDepH: EditText = findViewById(R.id.depreciationAdd_time)
        val editSvc: EditText = findViewById(R.id.serviceAdd_costs)
        val editEnergy: EditText = findViewById(R.id.energyAdd_consumption)


        savePrinter.setOnClickListener {
            val id: Int
            val item1 = editName.text.toString()
            val item2 = editDiam.text.toString().toDouble()
            val item3 = editPrice.text.toString().toDouble()
            val item4 = editDepH.text.toString().toDouble()
            val item5 = editSvc.text.toString().toDouble()
            val item6 = editEnergy.text.toString().toDouble()

            //AsyncTask.execute() {
            if (item1 != "" || !item3.equals(null)
                || !item4.equals(null) || !item6.equals(null)
            ) {
                id = pMap.addPrinterAndGetId(item1, item2, item3, item4, item5, item6)
                editor.putStringSet(id.toString(), pMap.toMutableString(pMap.getPrinterById(id)))
                editor.commit()
            } else {
                Toast.makeText(
                    this, "Important Fields have not been filled out",
                    Toast.LENGTH_SHORT
                ).show()
            }
            //}
        }

        backButton.setOnClickListener {
            val i = Intent(this, MainActivity::class.java)
            startActivity(i)
        }
    }
}

错误如下:

2020-12-03 21:58:27.983 20229-20229/com.example.calculator3dprinting E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.calculator3dprinting, PID: 20229
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.calculator3dprinting/com.example.calculator3dprinting.PrinterAddActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
        at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:118)
        at com.example.calculator3dprinting.PrinterAddActivity.<init>(PrinterAddActivity.kt:15)
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1243)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3182)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

感谢您提供的任何反馈:)

堆栈跟踪(错误报告的东西)向后读取 - 顶行告诉您错误,以及导致错误的一系列调用。它被分成几个部分,所以第二个 Caused by 部分告诉你是什么导致了上面的错误。它说你试图打电话给:

android.content.Context.getApplicationContext()

空引用 - 即您尝试调用 getApplicationContext() 应该是 Context 但实际上是空的东西。

向下几行(回溯导致崩溃的事情)它说你在 PrinterAddActivity 的初始化块中,并告诉你行号 (PrinterAddActivity.kt:15)。那就是你的问题所在


那只是向您展示了如何找出问题的根源!基本上你的问题是当你初始化 val sharedPreferences 时你指的是 applicationContext (在 Kotlin 中实际上是 getApplicationContext()) - 但是你的 Activity 当你首先创建它。这会在其生命周期的后期出现,因此在您尝试访问它时它为空。

这可能是 lazy 代表

的不错人选
private val sharedPreferences: SharedPreferences by lazy { applicationContext.getSharedPreferences("Printers", MODE_PRIVATE) }

确实是一样的,除了它在第一次访问时被延迟初始化 - 理想情况下,当 Activity 有它的上下文时,你会这样做,比如从 onCreate 开始!你目前不是 - editorthat 初始化时引用它。因此,您也需要将其包装在 lazy 中,但您可以完全放弃它并在进行编辑时调用 edit()